Skip to content

Commit 9ab5b38

Browse files
committed
refactor: 生のHTMLを扱うコンポーネントを追加
1 parent f0e6b02 commit 9ab5b38

File tree

9 files changed

+54
-42
lines changed

9 files changed

+54
-42
lines changed

website/src/components/templates/CategoryTemplate.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { FC } from "hono/jsx";
22
import type { CategoryBody, Page } from "../../types/model";
3+
import { HtmlContent } from "../ui/HtmlContent";
34
import BaseTemplate, { type BaseTemplateProps } from "./BaseTemplate";
45

56
export type CategoryTemplateProps = Omit<BaseTemplateProps, "page"> & {
@@ -24,7 +25,7 @@ export const CategoryTemplate: FC<CategoryTemplateProps> = ({
2425
nextPage={nextPage}
2526
>
2627
<h1 id="summary">{page.body.content.name}</h1>
27-
<div dangerouslySetInnerHTML={{ __html: page.body.content.details }} />
28+
<HtmlContent html={page.body.content.details} />
2829
<h2 id="definitions">定義</h2>
2930
<ul class="subgridded">
3031
{page.body.content.items.map((item) => (

website/src/components/templates/FuncTemplate.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
Tooltip,
88
} from "../ui";
99
import { DeprecationWarning } from "../ui/DeprecationWarning";
10+
import { HtmlContent } from "../ui/HtmlContent";
1011
import BaseTemplate, { type BaseTemplateProps } from "./BaseTemplate";
1112

1213
export type FuncTemplateProps = Omit<BaseTemplateProps, "page"> & {
@@ -46,10 +47,9 @@ export const FuncTemplate: FC<FuncTemplateProps> = ({
4647
</div>
4748
)}
4849

49-
<div
50-
class="my-4 text-gray-700 [&_img]:mx-auto [&_img]:block [&_img]:max-w-full"
51-
dangerouslySetInnerHTML={{ __html: content.details }}
52-
/>
50+
<div class="my-4 text-gray-700">
51+
<HtmlContent html={content.details} />
52+
</div>
5353

5454
<h2 id="parameters" class="flex items-baseline gap-1">
5555
引数
@@ -61,10 +61,9 @@ export const FuncTemplate: FC<FuncTemplateProps> = ({
6161
</div>
6262

6363
{content.example && (
64-
<div
65-
class="my-6 bg-gray-50 p-4 rounded-md border border-gray-200"
66-
dangerouslySetInnerHTML={{ __html: content.example }}
67-
/>
64+
<div class="my-6 bg-gray-50 p-4 rounded-md border border-gray-200">
65+
<HtmlContent html={content.example} />
66+
</div>
6867
)}
6968

7069
<div class="my-6">

website/src/components/templates/GroupTemplate.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
FunctionParameters,
77
Tooltip,
88
} from "../ui";
9+
import { HtmlContent } from "../ui/HtmlContent";
910
import BaseTemplate, { type BaseTemplateProps } from "./BaseTemplate";
1011

1112
export type GroupTemplateProps = Omit<BaseTemplateProps, "page"> & {
@@ -32,7 +33,7 @@ export const GroupTemplate: FC<GroupTemplateProps> = ({
3233
nextPage={nextPage}
3334
>
3435
<h1 id="summary">{content.title}</h1>
35-
<div dangerouslySetInnerHTML={{ __html: content.details }} />
36+
<HtmlContent html={content.details} />
3637

3738
{content.functions.length > 0 && (
3839
<>

website/src/components/templates/HtmlTemplate.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { FC } from "hono/jsx";
22
import type { HtmlBody, Page } from "../../types/model";
3+
import { HtmlContent } from "../ui/HtmlContent";
34
import BaseTemplate, { type BaseTemplateProps } from "./BaseTemplate";
45

56
export type HtmlTemplateProps = Omit<BaseTemplateProps, "page"> & {
@@ -23,7 +24,7 @@ export const HtmlTemplate: FC<HtmlTemplateProps> = ({
2324
previousPage={previousPage}
2425
nextPage={nextPage}
2526
>
26-
<div dangerouslySetInnerHTML={{ __html: page.body.content as string }} />
27+
<HtmlContent html={page.body.content} />
2728
</BaseTemplate>
2829
);
2930
};

website/src/components/templates/TypeTemplate.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { FC } from "hono/jsx";
22
import type { Page, TypeBody } from "../../types/model";
33
import { FunctionDisplay, Tooltip } from "../ui";
4+
import { HtmlContent } from "../ui/HtmlContent";
45
import { TypeIcon } from "../ui/TypeIcon";
56
import { type2href } from "../ui/type2href";
67
import BaseTemplate, { type BaseTemplateProps } from "./BaseTemplate";
@@ -32,7 +33,7 @@ export const TypeTemplate: FC<TypeTemplateProps> = ({
3233
<TypeIcon type={content.name} isHeading={true} />
3334
</h1>
3435

35-
<div dangerouslySetInnerHTML={{ __html: content.details }} />
36+
<HtmlContent html={content.details} />
3637

3738
{content.constructor && (
3839
<>

website/src/components/ui/FunctionDisplay.tsx

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { Func } from "../../types/model";
33
import { ChevronRightIcon } from "../icons";
44
import { FunctionDefinition } from "./FunctionDefinition";
55
import { FunctionParameters } from "./FunctionParameters";
6+
import { HtmlContent } from "./HtmlContent";
67

78
type FunctionDisplayProps = {
89
func: Func;
@@ -17,10 +18,7 @@ export const FunctionDisplay: FC<FunctionDisplayProps> = ({
1718
}) => {
1819
return (
1920
<>
20-
<div
21-
class="[&_img]:mx-auto [&_img]:block [&_img]:max-w-full"
22-
dangerouslySetInnerHTML={{ __html: func.details }}
23-
/>
21+
<HtmlContent html={func.details} />
2422

2523
<div class="my-4">
2624
<FunctionDefinition func={func} prefix={prefix} />
@@ -34,18 +32,16 @@ export const FunctionDisplay: FC<FunctionDisplayProps> = ({
3432
</div>
3533
例を表示
3634
</summary>
37-
<div
38-
class="mt-2 bg-white p-3 rounded-md border border-gray-200 text-sm [&_img]:mx-auto [&_img]:block [&_img]:max-w-full"
39-
dangerouslySetInnerHTML={{ __html: func.example }}
40-
/>
35+
<div class="mt-2 bg-white p-3 rounded-md border border-gray-200 text-sm">
36+
<HtmlContent html={func.example} />
37+
</div>
4138
</details>
4239
)}
4340

4441
{func.example && !isExampleFolding && (
45-
<div
46-
class="my-6 bg-gray-50 p-4 rounded-md border border-gray-200 [&_img]:mx-auto [&_img]:block [&_img]:max-w-full"
47-
dangerouslySetInnerHTML={{ __html: func.example }}
48-
/>
42+
<div class="my-6 bg-gray-50 p-4 rounded-md border border-gray-200">
43+
<HtmlContent html={func.example} />
44+
</div>
4945
)}
5046

5147
<div class="my-4">

website/src/components/ui/FunctionParameters.tsx

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { FC } from "hono/jsx";
22
import type { Func } from "../../types/model";
33
import { ChevronRightIcon } from "../icons";
4+
import { HtmlContent } from "./HtmlContent";
45
import { Tooltip } from "./Tooltip";
56
import { TypeIcon } from "./TypeIcon";
67
import { type2href } from "./type2href";
@@ -47,10 +48,9 @@ export const FunctionParameters: FC<FunctionParametersProps> = ({
4748
</div>
4849
</h4>
4950

50-
<div
51-
class="mb-3 text-gray-700"
52-
dangerouslySetInnerHTML={{ __html: param.details }}
53-
/>
51+
<div class="mb-3 text-gray-700">
52+
<HtmlContent html={param.details} />
53+
</div>
5454

5555
{param.strings.length > 0 && (
5656
<div class="mt-3">
@@ -64,10 +64,9 @@ export const FunctionParameters: FC<FunctionParametersProps> = ({
6464
<div class="mb-1">
6565
<code class="text-gray-800">{string.string}</code>
6666
</div>
67-
<div
68-
class="text-sm text-gray-700"
69-
dangerouslySetInnerHTML={{ __html: string.details }}
70-
/>
67+
<div class="text-sm text-gray-700">
68+
<HtmlContent html={string.details} />
69+
</div>
7170
</div>
7271
</li>
7372
))}
@@ -78,10 +77,9 @@ export const FunctionParameters: FC<FunctionParametersProps> = ({
7877
{param.default && (
7978
<p class="mt-3 text-sm">
8079
<span class="font-medium">デフォルト値:</span>{" "}
81-
<span
82-
class="text-gray-700"
83-
dangerouslySetInnerHTML={{ __html: param.default }}
84-
/>
80+
<span class="text-gray-700">
81+
<HtmlContent html={param.default} />
82+
</span>
8583
</p>
8684
)}
8785

@@ -93,10 +91,9 @@ export const FunctionParameters: FC<FunctionParametersProps> = ({
9391
</div>
9492
例を表示
9593
</summary>
96-
<div
97-
class="mt-2 bg-white p-3 rounded-md border border-gray-200 text-sm [&_img]:mx-auto [&_img]:block [&_img]:max-w-full"
98-
dangerouslySetInnerHTML={{ __html: param.example }}
99-
/>
94+
<div class="mt-2 bg-white p-3 rounded-md border border-gray-200 text-sm">
95+
<HtmlContent html={param.example} />
96+
</div>
10097
</details>
10198
)}
10299
</div>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { FC } from "hono/jsx";
2+
3+
export type HtmlContentProps = {
4+
html: string;
5+
};
6+
7+
export const HtmlContent: FC<HtmlContentProps> = ({ html }) => {
8+
return (
9+
<div
10+
class="[&_img]:mx-auto [&_img]:block [&_img]:max-w-full"
11+
// biome-ignore lint/security/noDangerouslySetInnerHtml: typst-docsで生成されたHTMLを表示する
12+
dangerouslySetInnerHTML={{ __html: html }}
13+
/>
14+
);
15+
};

website/src/components/ui/Tooltip.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { FC } from "hono/jsx";
22
import { HelpCircleIcon } from "../icons";
3+
import { HtmlContent } from "./HtmlContent";
34

45
type TooltipProps = {
56
kind:
@@ -101,7 +102,7 @@ export const Tooltip: FC<TooltipProps> = ({ kind }) => {
101102
transition-opacity duration-200 bg-gray-900 text-white p-2 rounded shadow-lg
102103
text-xs z-50 top-full mt-1 -left-4 w-64"
103104
>
104-
<div dangerouslySetInnerHTML={{ __html: content.desc }} />
105+
<HtmlContent html={content.desc} />
105106
</div>
106107
</div>
107108
</div>
@@ -119,7 +120,7 @@ export const Tooltip: FC<TooltipProps> = ({ kind }) => {
119120
transition-opacity duration-200 bg-gray-900 text-white p-2 rounded shadow-lg
120121
text-xs z-50 top-full mt-1 -left-4 w-64"
121122
>
122-
<div dangerouslySetInnerHTML={{ __html: content.desc }} />
123+
<HtmlContent html={content.desc} />
123124
</div>
124125
</div>
125126
);

0 commit comments

Comments
 (0)