##はじめに
react-markdownの目次の作り方を紹介します。
(もっといい方法あるかもです。。)
スタイリング0です
目次を押すと、該当の箇所に移動するだけのものを作ります。
##完成品
import ReactMarkdown from "react-markdown";
const body = `
## タイトル1
* おはよう。
* おはよう。
* おはよう。
* おはよう。
* おはよう。
* おはよう。
* おはよう。
* おはよう。
* おはよう。
## タイトル2
1. こんにちは。
2. こんにちは。
3. こんにちは。
1. こんにちは。
2. こんにちは。
3. こんにちは。
1. こんにちは。
2. こんにちは。
3. こんにちは。
## タイトル3
#### こんばんは
#### こんばんは
#### こんばんは
#### こんばんは
#### こんばんは
#### こんばんは`
export default function Home() {
const H2 = ({ node, ...props }) => {
return (
<h2 id={node.position?.start.line.toString()}>{props.children}</h2>
);
}
const ankerLink = ({ node, ...props }) => {
return (
<a href={"#"+node.position?.start.line.toString()}>{props.children}</a>
);
}
return (
<div>
{/* 目次 */}
<ReactMarkdown
allowedElements={["h2"]}
components={{
h2: ankerLink,
}}>
{body}
</ReactMarkdown>
{/* 本文 */}
<ReactMarkdown
components={{
h2: H2,
}}
>
{body}
</ReactMarkdown>
</div>
)
}
手順では↑を順番に書いていくだけです。
##手順
###ライブラリのインストール
yarn add react-markdown
###マークダウンで書いたものを表示させる
import ReactMarkdown from "react-markdown";
const body = `
## タイトル1
* おはよう。
* おはよう。
* おはよう。
* おはよう。
* おはよう。
* おはよう。
* おはよう。
* おはよう。
* おはよう。
## タイトル2
1. こんにちは。
2. こんにちは。
3. こんにちは。
1. こんにちは。
2. こんにちは。
3. こんにちは。
1. こんにちは。
2. こんにちは。
3. こんにちは。
## タイトル3
#### こんばんは
#### こんばんは
#### こんばんは
#### こんばんは
#### こんばんは
#### こんばんは`
export default function Home() {
return (
<div>
<ReactMarkdown>
{body}
</ReactMarkdown>
</div>
)
}
bodyがマークダウンで書いた内容ですね
ReactMarkdownのchildrenにbodyを渡します。
こうやって書くこともできます
<ReactMarkdown
children={body}
/>
これでマークダウンで書かれたものをhtmlとして表示することができます。
###見出しにidを与える
export default function Home() {
const H2 = ({ node, ...props }) => {
return (
<h2 id={node.position?.start.line.toString()}>{props.children}</h2>
);
}
return (
<div>
<ReactMarkdown
components={{
h2: H2,
}}
>
{body}
</ReactMarkdown>
</div>
)
}
componentsオプションを使うことで、要素を編集できます。
マークダウンのh2を自分で作ったh2にしています。
左に要素の指定、右に自分で作ったものを指定します。
今回はh2だけですが、h2とh3など複数指定できます。
nodeやporpsにどんな値が入っているかはconsole.logなどで確認してみてください。
###見出しだけを表示させる
<ReactMarkdown allowedElements={["h2"]}>
{body}
</ReactMarkdown>
これでh2のみが表示されます。
<ReactMarkdown allowedElements={["h2"]}>
{body}
</ReactMarkdown>
<ReactMarkdown
components={{
h2: H2,
}}
>
{body}
</ReactMarkdown>
目次ようと本文用で2つ作ります。
###見出しから飛べるようにする
const ankerLink = ({ node, ...props }) => {
return (
<a href={"#"+node.position?.start.line.toString()}>{props.children}</a>
);
}
<ReactMarkdown
allowedElements={["h2"]}
components={{
h2: ankerLink,
}}>
{body}
</ReactMarkdown>
見出しだけを表示している方のh2を編集します。
見出しにidを与えると同じようにh2を編集します
同じマークダウンを使っているので、idが同じになります。
これで目次をクリックすることで、見出しに飛ぶことができるようになりました。
あとは、自由にスタイリングしていってください。
おまけ
このままだと、headerなどがある時に被ってしまいます。
H2に、「paddidng-top: 20px;」、「margin-top: -20px;」などを持たせることでいい感じに表示できます。
参考文献