customization-guide > カスタムコンポーネントの使用方法
カスタムコンポーネントの使用方法
ノーションプレッソは、様々なノーションのブロックタイプに対する基本コンポーネントを提供します。このセクションでは、これらの基本コンポーネントの使用方法とカスタマイズ方法、そして新しいカスタムコンポーネントを作成する方法を説明します。
基本コンポーネントの使用例
Headingコンポーネント
Headingコンポーネントは、ノーションの見出しブロックをレンダリングします。以下はHeadingコンポーネントをカスタマイズする例です:
import React from "react";
import { Heading, type HeadingArgs } from "@notionpresso/react";
const CustomHeading: React.FC<HeadingArgs> = (props) => {
// level 3 ヘディングに下線を追加
if (props.type === "heading_3") {
return <Heading {...props} style={{ textDecoration: "underline" }} />;
}
return <Heading {...props} />;
};
export default CustomHeading;
この例では、level
属性を確認して、特定のレベルのヘディングに対してスタイルを変更しています。
Paragraphコンポーネント
Paragraphコンポーネントは、一般的なテキストブロックをレンダリングします。以下はParagraphコンポーネントをカスタマイズする例です:
import React from "react";
import { Paragraph, type ParagraphArgs } from "@notionpresso/react";
const CustomParagraph: React.FC<ParagraphArgs> = (props) => {
return (
<Paragraph
{...props}
className="custom-paragraph"
style={{ lineHeight: "1.8", marginBottom: "1em" }}
/>
);
};
export default CustomParagraph;
この例では、すべての段落に対して行間と下の余白を調整し、ユーザー定義のクラスを追加しています。
Toggleコンポーネントのカスタマイズ例
Toggleコンポーネントは、ノーションのトグルブロックを実装します。以下はToggleコンポーネントをカスタマイズする高度な例です:
import React, { useState } from "react";
import { Toggle, type ToggleArgs } from "@notionpresso/react";
import { ChevronDown, ChevronRight } from "your-icon-library";
const CustomToggle: React.FC<ToggleArgs> = (props) => {
const [isOpen, setIsOpen] = useState(false);
const handleChangeOpen = (open: boolean) => {
setIsOpen(open);
// ここに追加のロジックを追加できます。
console.log(`Toggle state changed to: ${open}`);
};
return (
<Toggle {...props} isOpen={isOpen} onChangeOpen={handleChangeOpen}>
<Toggle.Icon>
{isOpen ? <ChevronDown size={20} /> : <ChevronRight size={20} />}
</Toggle.Icon>
<Toggle.Content>{props.children}</Toggle.Content>
</Toggle>
);
};
export default CustomToggle;
この例では:
useState
を使用してトグルの開閉状態を管理します。handleChangeOpen
関数を使用して状態の変更を処理し、必要に応じて追加のロジックを実装できます。Toggle
コンポーネントにisOpen
とonChangeOpen
プロップを渡して状態を直接制御します。isOpen
状態に応じて異なるアイコンを表示します。
<Toggle.Icon>
にコンテンツを提供しない場合、デフォルトのアイコンが使用されます。
カスタムコンポーネントの適用
ノーションプレッソでカスタムコンポーネントを使用する方法は以下の通りです:
import { Notion } from "@notionpresso/react";
import CustomHeading from "./CustomHeading";
import CustomParagraph from "./CustomParagraph";
import CustomToggle from "./CustomToggle";
const MyNotionPage = ({ pageData }) => {
const customComponents = {
heading_1: CustomHeading,
heading_2: CustomHeading,
heading_3: CustomHeading,
paragraph: CustomParagraph,
toggle: CustomToggle,
};
return (
<Notion custom={customComponents}>
<Notion.Body>
<Notion.Blocks blocks={pageData.blocks} />
</Notion.Body>
</Notion>
);
};
この例では、custom
プロップを使用してカスタムコンポーネントをNotionコンポーネントに渡します。各ブロックタイプに対してカスタムコンポーネントを指定できます。
完全なカスタムコンポーネントの作成
ノーションプレッソの基本コンポーネントを使用せずに、完全に新しいコンポーネントを作成することも可能です。以下はTodoコンポーネントを最初から作成する例です:
import React from "react";
import { RichText, type TodoProps } from "@notionpresso/react";
const Todo: React.FC<TodoProps> = ({ children, ...props }) => {
const {
to_do: { color, rich_text: texts, checked },
} = props;
const colorClass = color !== "default" ? `notion-${color}` : "";
return (
<div className={`notion-block notion-to-do ${colorClass}`}>
<div className="notion-to-do-item">
<div className="notion-to-do-item-content">
<input
type="checkbox"
checked={checked}
readOnly
className="notion-to-do-checkbox"
/>
<div
className={`notion-to-do-text ${checked ? "notion-to-do-checked" : ""}`}
>
<RichText props={texts} />
</div>
</div>
{children}
</div>
</div>
);
};
export default Todo;
この例では、以下の点に注意してください:
- RichTextコンポーネントのみNotionpressoからインポートします。これは複雑なテキストレンダリングを処理するためです。
- CSSクラス名はすべてnotion-で始まります。これはNotionpressoのスタイルルールに従っているためです。
- gnotion-${color}形式のクラスを追加します。デフォルトの色("default")の場合、追加のクラスは適用されません。
- コンポーネントはchildrenプロップを受け取り、サブコンテンツをレンダリングできるようにします。これは入れ子構造をサポートするためです。
コンポーネントの作成時に注意すべき点
- 型の安全性: TypeScriptを使用してpropの型を明確に定義してください。Notionpressoから提供される型(例:
HeadingArgs
,ParagraphArgs
)を使用してください。 - propの渡し: カスタムコンポーネントで基本コンポーネントにすべてのpropを渡す場合、
{...props}
を使用してください。これは型の安全性を維持しながら不要なpropの列挙を避けるためです。 - スタイルのオーバーライド: 既存のスタイルを完全に置き換えるのではなく、
className
を追加するか、style
プロップを拡張する方法を使用してください。 - パフォーマンスの考慮: 不要なリレンダリングを避けるために、
React.memo
やuseMemo
,useCallback
を適切に使用してください。 - アクセシビリティ: カスタムコンポーネントを作成する際にアクセシビリティ(a11y)を考慮してください。例えば、トグルボタンに適切な
aria-
属性を追加することが推奨されます。 - テーマのサポート: Notionpressoのテーマシステムと互換性があるように、カスタムコンポーネントを設計してください。CSS変数を使用すると、ダークモードなどのテーマの切り替えを簡単にサポートできます。
カスタムコンポーネントの適用
ノーションプレッソでカスタムコンポーネントを使用する方法は以下の通りです:
import { Notion, type NotionPage, type CustomComponents } from 'Notionpresso';
import CustomParagraph from './CustomParagraph';
import CustomToggle from './CustomToggle';
const MyNotionPage = ({ pageData }: { pageData: NotionPage }) => {
const customComponents = useMemo<CustomComponents>(() => ({
paragraph: CustomParagraph,
toggle: CustomToggle,
}), []);
return (
<Notion custom={customComponents}>
<Notion.Cover cover={pageData.cover} />
<Notion.Body>
<Notion.Title title={pageData.title} />
<Notion.Blocks blocks={pageData.blocks} />
</Notion.Body>
</Notion>
);
};
この例では、custom
プロップを使用してカスタムコンポーネントをNotionコンポーネントに渡します。
これらのガイドラインに従うことで、Notionpressoの機能を拡張しながら、一貫性と保守性を維持できます。