diff --git a/packages/react-notion-custom/CONTRIBUTING-KR.md b/packages/react-notion-custom/CONTRIBUTING-KR.md index d7aed95..34a1714 100644 --- a/packages/react-notion-custom/CONTRIBUTING-KR.md +++ b/packages/react-notion-custom/CONTRIBUTING-KR.md @@ -649,11 +649,11 @@ fetchNotionPage(); | Heading 3 | ✅ Yes | `heading_3` | | | Bulleted List Item | ❌ No | `bulleted_list_item` | | | Numbered List Item | ❌ No | `numbered_list_item` | | -| To-do | ❌ No | `to_do` | | +| To-do | ✅ Yes | `to_do` | | | Toggle | ✅ Yes | `toggle` | | | Quote | ❌ No | `quote` | | | Callout | ❌ No | `callout` | | -| Equation | ❌ No | `equation` | | +| Equation | ✅ Yes | `equation` | | | Code | ❌ No | `code` | | | Image | ❌ No | `image` | | | Video | ❌ No | `video` | | diff --git a/packages/react-notion-custom/CONTRIBUTING.md b/packages/react-notion-custom/CONTRIBUTING.md index 54e9e85..ad3564d 100644 --- a/packages/react-notion-custom/CONTRIBUTING.md +++ b/packages/react-notion-custom/CONTRIBUTING.md @@ -652,11 +652,11 @@ Here's a list of Notion block types currently supported in react-notion-custom. | Heading 3 | ✅ Yes | `heading_3` | | | Bulleted List Item | ❌ No | `bulleted_list_item` | | | Numbered List Item | ❌ No | `numbered_list_item` | | -| To-do | ❌ No | `to_do` | | +| To-do | ✅ Yes | `to_do` | | | Toggle | ✅ Yes | `toggle` | | | Quote | ❌ No | `quote` | | | Callout | ❌ No | `callout` | | -| Equation | ❌ No | `equation` | | +| Equation | ✅ Yes | `equation` | | | Code | ❌ No | `code` | | | Image | ❌ No | `image` | | | Video | ❌ No | `video` | | diff --git a/packages/react-notion-custom/src/lib/components/index.ts b/packages/react-notion-custom/src/lib/components/index.ts index b0e4710..d5e9cbd 100644 --- a/packages/react-notion-custom/src/lib/components/index.ts +++ b/packages/react-notion-custom/src/lib/components/index.ts @@ -2,8 +2,9 @@ import Headings from "./headings"; import Paragraph from "./paragraph"; import Toggle from "./toggle"; import Equation from "./equation"; +import Todo from "./todo"; -export { Headings, Paragraph, Toggle, Equation }; +export { Headings, Paragraph, Toggle, Equation, Todo }; export default { heading_1: Headings, @@ -12,4 +13,5 @@ export default { paragraph: Paragraph, toggle: Toggle, equation: Equation, + to_do: Todo, }; diff --git a/packages/react-notion-custom/src/lib/components/todo.tsx b/packages/react-notion-custom/src/lib/components/todo.tsx new file mode 100644 index 0000000..54f6fd2 --- /dev/null +++ b/packages/react-notion-custom/src/lib/components/todo.tsx @@ -0,0 +1,85 @@ +import React, { useState, useCallback } from "react"; +import type { TodoArgs } from "../types"; +import { getColorCss } from "../utils"; +import RichText from "./internal/rich-text"; + +type TodoProps = { + children?: React.ReactNode; +} & TodoArgs; + +const Todo: React.FC = ({ children, ...props }) => { + const { + to_do: { color, rich_text: texts, checked: initialChecked }, + } = props; + const [checked, setChecked] = useState(initialChecked); + + const handleToggle = useCallback(() => { + setChecked((prev) => !prev); + }, []); + + return ( +
+
+
+ +
+

+ +

+
+ {children} +
+ ); +}; + +export default Todo; + +const CheckBox: React.FC<{ checked: boolean; onChange: () => void }> = ({ + checked, + onChange, +}) => { + return ( +
+ {checked ? ( + + + + ) : ( + + + + )} +
+ ); +}; diff --git a/packages/react-notion-custom/src/lib/index.css b/packages/react-notion-custom/src/lib/index.css index 55f4716..0a056bc 100644 --- a/packages/react-notion-custom/src/lib/index.css +++ b/packages/react-notion-custom/src/lib/index.css @@ -590,3 +590,51 @@ .notion-equation:focus { background: var(--select-color-2); } + +.notion-to-do-content { + display: flex; +} + +.notion-to-do-checkbox { + display: inline-block; + padding: 8px 6px; +} + +.notion-to-do-text { + padding: 3px 2px; +} + +.notion-to-do-checked .notion-to-do-text { + text-decoration: line-through; + opacity: 0.6; +} + +.notion-property-checkbox { + width: 16px; + height: 16px; +} + +.notion-property-checkbox-checked { + width: 16px; + height: 16px; + background: var(--select-color-0); +} + +.notion-property-checkbox-checked svg { + position: relative; + display: block; + top: 1px; + left: 1px; + width: 14px; + height: 14px; + fill: #fff; +} + +.notion-property-checkbox-unchecked { + width: 16px; + height: 16px; +} + +.notion-property-checkbox-unchecked svg { + fill: var(--fg-color); +} diff --git a/packages/story/src/stories/todo/todo.json b/packages/story/src/stories/todo/todo.json new file mode 100644 index 0000000..1fa792e --- /dev/null +++ b/packages/story/src/stories/todo/todo.json @@ -0,0 +1,582 @@ +{ + "object": "page", + "id": "591d29d3-cb19-4273-bb3a-82644ed4faa4", + "created_time": "2022-12-28T23:30:00.000Z", + "last_edited_time": "2023-01-07T04:39:00.000Z", + "created_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "last_edited_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "cover": { + "type": "external", + "external": { + "url": "https://www.notion.so/images/page-cover/solid_beige.png" + } + }, + "icon": null, + "parent": { + "type": "database_id", + "database_id": "be65d799-9e98-4426-86a6-72072991e27b" + }, + "archived": false, + "properties": { + "HashTags": { + "id": "Hhkx", + "type": "multi_select", + "multi_select": [] + }, + "생성 일시": { + "id": "J%7C%3BZ", + "type": "created_time", + "created_time": "2022-12-28T23:30:00.000Z" + }, + "Slug": { + "id": "S%3A%7B%3E", + "type": "rich_text", + "rich_text": [ + { + "type": "text", + "text": { + "content": "test", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "test", + "href": null + } + ] + }, + "Description": { + "id": "qTV%3E", + "type": "rich_text", + "rich_text": [] + }, + "Status": { + "id": "vu%7C%3B", + "type": "select", + "select": { + "id": "|QrX", + "name": "Publishable", + "color": "green" + } + }, + "Name": { + "id": "title", + "type": "title", + "title": [ + { + "type": "text", + "text": { + "content": "테스트 paragrap", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "테스트 paragrap", + "href": null + } + ] + } + }, + "url": "https://www.notion.so/paragrap-591d29d3cb194273bb3a82644ed4faa4", + "blocks": [ + { + "object": "block", + "id": "06d7c6ab-cb38-4039-bde8-fec3b85ea728", + "parent": { + "type": "page_id", + "page_id": "591d29d3-cb19-4273-bb3a-82644ed4faa4" + }, + "created_time": "2023-01-07T04:10:00.000Z", + "last_edited_time": "2023-01-07T04:38:00.000Z", + "created_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "last_edited_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "has_children": false, + "archived": false, + "type": "paragraph", + "paragraph": { + "color": "gray_background", + "rich_text": [] + } + }, + { + "object": "block", + "id": "0c0b6e3f-6022-40dc-b4c3-05c2735ee835", + "parent": { + "type": "page_id", + "page_id": "591d29d3-cb19-4273-bb3a-82644ed4faa4" + }, + "created_time": "2023-01-07T04:38:00.000Z", + "last_edited_time": "2023-01-07T04:38:00.000Z", + "created_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "last_edited_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "has_children": true, + "archived": false, + "type": "to_do", + "to_do": { + "checked": false, + "color": "default", + "rich_text": [ + { + "type": "text", + "text": { + "content": "todo1", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "todo1", + "href": null + } + ] + }, + "blocks": [ + { + "object": "block", + "id": "f2941a3f-ac21-46fd-92bd-1c36d66b2844", + "parent": { + "type": "block_id", + "block_id": "0c0b6e3f-6022-40dc-b4c3-05c2735ee835" + }, + "created_time": "2023-01-07T04:38:00.000Z", + "last_edited_time": "2023-01-07T04:38:00.000Z", + "created_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "last_edited_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "has_children": false, + "archived": false, + "type": "paragraph", + "paragraph": { + "color": "blue_background", + "rich_text": [ + { + "type": "text", + "text": { + "content": "nest paragraph", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "nest paragraph", + "href": null + } + ] + } + } + ] + }, + { + "object": "block", + "id": "131d41ef-0959-4e8e-a7bd-3ff6ab5b41b7", + "parent": { + "type": "page_id", + "page_id": "591d29d3-cb19-4273-bb3a-82644ed4faa4" + }, + "created_time": "2023-01-07T04:38:00.000Z", + "last_edited_time": "2023-01-07T04:38:00.000Z", + "created_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "last_edited_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "has_children": true, + "archived": false, + "type": "to_do", + "to_do": { + "checked": true, + "color": "default", + "rich_text": [ + { + "type": "text", + "text": { + "content": "todo2", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "todo2", + "href": null + } + ] + }, + "blocks": [ + { + "object": "block", + "id": "9659845e-fe5b-4684-8afd-78c670e90c25", + "parent": { + "type": "block_id", + "block_id": "131d41ef-0959-4e8e-a7bd-3ff6ab5b41b7" + }, + "created_time": "2023-01-07T04:38:00.000Z", + "last_edited_time": "2023-01-07T04:38:00.000Z", + "created_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "last_edited_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "has_children": false, + "archived": false, + "type": "to_do", + "to_do": { + "checked": false, + "color": "blue_background", + "rich_text": [ + { + "type": "text", + "text": { + "content": "nest todo 1", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "nest todo 1", + "href": null + } + ] + } + }, + { + "object": "block", + "id": "071e179b-4104-4939-9c5f-76a4f4426940", + "parent": { + "type": "block_id", + "block_id": "131d41ef-0959-4e8e-a7bd-3ff6ab5b41b7" + }, + "created_time": "2023-01-07T04:38:00.000Z", + "last_edited_time": "2023-01-07T04:39:00.000Z", + "created_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "last_edited_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "has_children": false, + "archived": false, + "type": "to_do", + "to_do": { + "checked": true, + "color": "default", + "rich_text": [ + { + "type": "text", + "text": { + "content": "nest todo 2", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "nest todo 2", + "href": null + } + ] + } + } + ] + }, + { + "object": "block", + "id": "e77001a4-9b1b-40ea-9349-a73d022e7d87", + "parent": { + "type": "page_id", + "page_id": "591d29d3-cb19-4273-bb3a-82644ed4faa4" + }, + "created_time": "2023-01-07T03:39:00.000Z", + "last_edited_time": "2023-01-07T04:10:00.000Z", + "created_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "last_edited_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "has_children": false, + "archived": false, + "type": "paragraph", + "paragraph": { + "color": "gray_background", + "rich_text": [] + } + }, + { + "object": "block", + "id": "f938d548-9cdb-4250-8f51-2b49af2598f8", + "parent": { + "type": "page_id", + "page_id": "591d29d3-cb19-4273-bb3a-82644ed4faa4" + }, + "created_time": "2023-01-07T04:08:00.000Z", + "last_edited_time": "2023-01-07T04:39:00.000Z", + "created_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "last_edited_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "has_children": true, + "archived": false, + "type": "paragraph", + "paragraph": { + "color": "gray_background", + "rich_text": [] + }, + "blocks": [ + { + "object": "block", + "id": "4f450777-4131-4750-ae22-fa36f3bd7169", + "parent": { + "type": "block_id", + "block_id": "f938d548-9cdb-4250-8f51-2b49af2598f8" + }, + "created_time": "2023-01-07T03:39:00.000Z", + "last_edited_time": "2023-01-07T04:36:00.000Z", + "created_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "last_edited_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "has_children": false, + "archived": false, + "type": "paragraph", + "paragraph": { + "color": "blue_background", + "rich_text": [ + { + "type": "text", + "text": { + "content": "nest paragraph", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "nest paragraph", + "href": null + } + ] + } + }, + { + "object": "block", + "id": "e3755c16-6e1b-4efb-9f88-a9e5df023933", + "parent": { + "type": "block_id", + "block_id": "f938d548-9cdb-4250-8f51-2b49af2598f8" + }, + "created_time": "2023-01-07T04:39:00.000Z", + "last_edited_time": "2023-01-07T04:39:00.000Z", + "created_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "last_edited_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "has_children": false, + "archived": false, + "type": "to_do", + "to_do": { + "checked": false, + "color": "purple_background", + "rich_text": [ + { + "type": "text", + "text": { + "content": "todo1", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "todo1", + "href": null + } + ] + } + }, + { + "object": "block", + "id": "598b1910-1bf5-4c1f-a0e0-a8a0ce7608c6", + "parent": { + "type": "block_id", + "block_id": "f938d548-9cdb-4250-8f51-2b49af2598f8" + }, + "created_time": "2023-01-07T04:39:00.000Z", + "last_edited_time": "2023-01-07T04:39:00.000Z", + "created_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "last_edited_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "has_children": false, + "archived": false, + "type": "to_do", + "to_do": { + "checked": true, + "color": "default", + "rich_text": [ + { + "type": "text", + "text": { + "content": "todo2", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "todo2", + "href": null + } + ] + } + } + ] + }, + { + "object": "block", + "id": "a199ef95-dd63-4812-a43c-1f8a84ac6fd3", + "parent": { + "type": "page_id", + "page_id": "591d29d3-cb19-4273-bb3a-82644ed4faa4" + }, + "created_time": "2023-01-07T04:37:00.000Z", + "last_edited_time": "2023-01-07T04:37:00.000Z", + "created_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "last_edited_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "has_children": false, + "archived": false, + "type": "paragraph", + "paragraph": { + "color": "default", + "rich_text": [] + } + }, + { + "object": "block", + "id": "23d49ee9-d260-4b92-9ba8-999570eb91ee", + "parent": { + "type": "page_id", + "page_id": "591d29d3-cb19-4273-bb3a-82644ed4faa4" + }, + "created_time": "2023-01-07T04:30:00.000Z", + "last_edited_time": "2023-01-07T04:30:00.000Z", + "created_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "last_edited_by": { + "object": "user", + "id": "95fc0174-8fc6-4114-8e45-f67eacd99f07" + }, + "has_children": false, + "archived": false, + "type": "paragraph", + "paragraph": { + "color": "default", + "rich_text": [] + } + } + ] +} diff --git a/packages/story/src/stories/todo/todo.stories.tsx b/packages/story/src/stories/todo/todo.stories.tsx new file mode 100644 index 0000000..ece4c91 --- /dev/null +++ b/packages/story/src/stories/todo/todo.stories.tsx @@ -0,0 +1,20 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import Component from "../../lib/Notion"; +import json from "./todo.json"; + +const blocks = json.blocks as any; + +const meta: Meta = { + title: "Blocks/Todo", + component: Component, +}; + +export default meta; +type Story = StoryObj; + +export const Todo: Story = { + args: { + title: "Todo", + blocks: blocks, + }, +};