customization-guide > 自定义组件使用指南
自定义组件使用指南
Notionpresso 为各种 Notion 块类型提供了基本组件。本节将说明如何使用和自定义这些基本组件,以及如何创建新的自定义组件。
基本组件使用示例
Heading 组件
Heading 组件用于渲染 Notion 的标题块。以下是自定义 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 组件用于实现 Notion 的切换块。以下是自定义 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
prop将状态直接传递给组件。- 根据
isOpen
状态显示不同的图标。
如果 <Toggle.Icon>
中没有提供内容,则使用默认图标。
应用自定义组件
在 Notionpresso 中使用自定义组件的方法如下:
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
prop将自定义组件传递给 Notion 组件。可以为每个块类型指定自定义组件。
创建完整的自定义组件
可以完全从头开始创建新的组件,而不是使用 Notionpresso 的基本组件。以下是创建 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 组件,因为这是处理复杂文本渲染的唯一方法。
- CSS 类名必须以
notion-
开头,因为这是 Notionpresso 样式规则的要求。 - 添加
gnotion-${color}
形式的类,因为默认颜色("default")不需要额外类。 - 组件可以通过
children
prop接收子内容,以支持嵌套结构。
组件编写时的注意事项
- 类型安全性: 使用 TypeScript 明确定义 prop 类型,并利用 Notionpresso 提供的类型(例如
HeadingArgs
,ParagraphArgs
)。 - prop 传递: 如果要在自定义组件中使用基本组件的所有 prop,请使用
{...props}
。这有助于保持类型安全性,并避免不必要的 prop 列出。 - 样式覆盖: 注意不要完全覆盖现有样式,而是通过添加
className
或扩展style
prop 来使用。 - 性能考虑: 为了防止不必要的重新渲染,请适当使用
React.memo
,useMemo
,useCallback
。 - 可访问性: 在创建自定义组件时,请考虑可访问性(a11y)。例如,为切换按钮添加适当的
aria-
属性。 - 主题支持: 请设计自定义组件,以便与 Notionpresso 的主题系统兼容。使用 CSS 变量可以轻松支持暗模式等主题切换。
应用自定义组件
在 Notionpresso 中使用自定义组件的方法如下:
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
prop将自定义组件传递给 Notion 组件。
遵循这些指南,可以在扩展 Notionpresso 功能的同时保持一致性和可维护性。