Skip to content

Commit 44b281e

Browse files
authored
Merge pull request #85 from 01-binary/refactor
Refactor
2 parents 3968cad + 36b54f7 commit 44b281e

File tree

27 files changed

+403
-419
lines changed

27 files changed

+403
-419
lines changed

.changeset/few-oranges-tickle.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"notion-to-jsx": patch
3+
---
4+
5+
refactor: components to use TypeScript types and remove React imports

packages/notion-to-jsx/src/components/Cover/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useState } from 'react';
22
import { coverContainer, skeletonWrapper, imageStyle } from './styles.css';
33
import Skeleton from '../Skeleton';
44

5-
interface CoverProps {
5+
interface Props {
66
src: string;
77
alt: string;
88
}
@@ -11,7 +11,7 @@ interface CoverProps {
1111
* 노션 페이지 상단에 표시되는 커버 이미지 컴포넌트
1212
* 이미지 로딩 중에는 스켈레톤 UI를 표시하고, 로딩 완료 시 자연스럽게 이미지로 전환됩니다.
1313
*/
14-
const Cover = ({ src, alt }: CoverProps) => {
14+
const Cover = ({ src, alt }: Props) => {
1515
const [isLoaded, setIsLoaded] = useState(false);
1616

1717
return (

packages/notion-to-jsx/src/components/Renderer/components/Block/BlockRenderer.tsx

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import React from 'react';
2-
31
import {
42
MemoizedRichText,
53
MemoizedImage,
@@ -12,76 +10,63 @@ import { ColumnList } from '../Column';
1210
import { Quote } from '../Quote';
1311
import Table from '../Table';
1412
import { Toggle } from '../Toggle';
13+
import { NotionBlock } from '../../../../types';
1514

1615
export interface Props {
17-
block: any;
18-
onFocus?: () => void;
19-
index: number;
16+
block: NotionBlock;
2017
isColumn?: boolean;
2118
}
2219

23-
const BlockRenderer: React.FC<Props> = ({
24-
block,
25-
onFocus,
26-
index,
27-
isColumn = false,
28-
}) => {
20+
const BlockRenderer = ({ block, isColumn = false }: Props) => {
2921
if (!block) return null;
3022

31-
const blockProps = {
32-
tabIndex: 0,
33-
onFocus,
34-
};
35-
3623
switch (block.type) {
3724
case 'link_preview':
38-
return (
39-
<MemoizedLinkPreview url={block.link_preview.url} {...blockProps} />
40-
);
25+
return <MemoizedLinkPreview url={block.link_preview.url} />;
4126
case 'paragraph':
4227
return (
43-
<Paragraph {...blockProps}>
28+
<Paragraph>
4429
<MemoizedRichText richTexts={block.paragraph.rich_text} />
4530
</Paragraph>
4631
);
4732

4833
case 'heading_1':
4934
return (
50-
<Heading1 {...blockProps}>
35+
<Heading1>
5136
<MemoizedRichText richTexts={block.heading_1.rich_text} />
5237
</Heading1>
5338
);
5439

5540
case 'heading_2':
5641
return (
57-
<Heading2 {...blockProps}>
42+
<Heading2>
5843
<MemoizedRichText richTexts={block.heading_2.rich_text} />
5944
</Heading2>
6045
);
6146

6247
case 'heading_3':
6348
return (
64-
<Heading3 {...blockProps}>
49+
<Heading3>
6550
<MemoizedRichText richTexts={block.heading_3.rich_text} />
6651
</Heading3>
6752
);
6853

6954
case 'code':
7055
return (
71-
<div {...blockProps}>
56+
<div>
7257
<CodeBlock
73-
code={block.code.rich_text[0].text.content}
58+
code={block.code.rich_text[0]?.text?.content || ''}
7459
language={block.code.language}
75-
caption={block.code.caption?.[0]?.plain_text}
60+
caption={block.code.caption}
7661
/>
7762
</div>
7863
);
7964

8065
case 'image':
8166
return (
82-
<figure {...blockProps}>
67+
<figure>
8368
<MemoizedImage
84-
src={block.image.file?.url || block.image.external?.url}
69+
src={block.image.file?.url || block.image.external?.url || ''}
8570
alt={block.image.caption?.[0]?.plain_text || ''}
8671
caption={block.image.caption}
8772
format={block.image.format}
@@ -99,26 +84,20 @@ const BlockRenderer: React.FC<Props> = ({
9984
);
10085

10186
case 'column_list':
102-
return <ColumnList block={block} onFocus={onFocus} />;
87+
return <ColumnList block={block} />;
10388

10489
case 'column':
10590
// 개별 column은 ColumnList에서 처리됩니다
10691
return null;
10792

10893
case 'quote':
109-
return <Quote richTexts={block.quote.rich_text} {...blockProps} />;
94+
return <Quote richTexts={block.quote.rich_text} />;
11095

11196
case 'table':
112-
return <Table block={block} tabIndex={blockProps.tabIndex} />;
97+
return <Table block={block} />;
11398

11499
case 'toggle':
115-
return (
116-
<Toggle
117-
block={block}
118-
tabIndex={blockProps.tabIndex}
119-
onFocus={onFocus}
120-
/>
121-
);
100+
return <Toggle block={block} />;
122101

123102
default:
124103
return null;

packages/notion-to-jsx/src/components/Renderer/components/Bookmark/Bookmark.tsx

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import React from 'react';
21
import {
32
link,
43
card,
@@ -11,22 +10,14 @@ import {
1110
favicon,
1211
urlText,
1312
} from './styles.css';
13+
import { OpenGraphData } from './type';
1414

15-
interface OpenGraphData {
16-
title: string;
17-
description: string;
18-
image: string;
19-
siteName: string;
20-
url: string;
21-
favicon?: string;
22-
}
23-
24-
export interface BookmarkProps {
15+
export interface Props {
2516
url: string;
2617
metadata?: OpenGraphData;
2718
}
2819

29-
const Bookmark: React.FC<BookmarkProps> = ({ url, metadata }) => {
20+
const Bookmark = ({ url, metadata }: Props) => {
3021
return (
3122
<a href={url} target="_blank" rel="noopener noreferrer" className={link}>
3223
<div className={card}>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export interface OpenGraphData {
2+
title: string;
3+
description: string;
4+
image: string;
5+
siteName: string;
6+
url: string;
7+
favicon?: string;
8+
}

packages/notion-to-jsx/src/components/Renderer/components/Code/CodeBlock.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useMemo } from 'react';
1+
import { ReactNode, useMemo } from 'react';
22
import { codeBlock } from './styles.css';
33
import Prism, { Grammar, Token } from 'prismjs';
44
import { MemoizedRichText } from '../MemoizedComponents';
@@ -12,19 +12,13 @@ if (typeof window !== 'undefined') {
1212
window.Prism = Prism;
1313
}
1414

15-
export interface Props {
16-
code: string;
17-
language: string;
18-
caption?: RichTextItem[];
19-
}
20-
21-
const renderToken = (token: string | Token, i: number): React.ReactNode => {
15+
const renderToken = (token: string | Token, i: number): ReactNode => {
2216
if (typeof token === 'string') {
2317
return <span key={i}>{token}</span>;
2418
}
2519

2620
const content = token.content;
27-
let tokenContent: React.ReactNode;
21+
let tokenContent: ReactNode;
2822

2923
if (Array.isArray(content)) {
3024
tokenContent = content.map((subToken, j) => renderToken(subToken, j));
@@ -41,7 +35,13 @@ const renderToken = (token: string | Token, i: number): React.ReactNode => {
4135
);
4236
};
4337

44-
const CodeBlock: React.FC<Props> = ({ code, language, caption }) => {
38+
export interface Props {
39+
code: string;
40+
language: string;
41+
caption?: RichTextItem[];
42+
}
43+
44+
const CodeBlock = ({ code, language, caption }: Props) => {
4545
const tokens = useMemo(() => {
4646
const prismLanguage =
4747
Prism.languages[language] || Prism.languages.plaintext;

packages/notion-to-jsx/src/components/Renderer/components/Column/Column.tsx

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,18 @@
1-
import React from 'react';
1+
import { ColumnBlock } from '../../../../types';
22
import BlockRenderer from '../Block/BlockRenderer';
33
import { columnContainer } from './styles.css';
44

55
export interface ColumnProps {
6-
block: any;
7-
onFocus?: () => void;
6+
block: ColumnBlock;
87
}
98

10-
const Column: React.FC<ColumnProps> = ({ block, onFocus }) => {
9+
const Column = ({ block }: ColumnProps) => {
1110
if (!block || !block.children) return null;
1211

1312
return (
1413
<div className={columnContainer}>
15-
{block.children.map((childBlock: any, index: number) => (
16-
<BlockRenderer
17-
key={childBlock.id}
18-
block={childBlock}
19-
onFocus={onFocus}
20-
index={index}
21-
isColumn
22-
/>
14+
{block.children.map((childBlock) => (
15+
<BlockRenderer key={childBlock.id} block={childBlock} isColumn />
2316
))}
2417
</div>
2518
);

packages/notion-to-jsx/src/components/Renderer/components/Column/ColumnList.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
1-
import React from 'react';
21
import Column from './Column';
32
import { columnListContainer } from './styles.css';
3+
import { ColumnListBlock } from '../../../../types';
44

55
export interface ColumnListProps {
6-
block: any;
7-
onFocus?: () => void;
6+
block: ColumnListBlock;
87
}
98

10-
const ColumnList: React.FC<ColumnListProps> = ({ block, onFocus }) => {
9+
const ColumnList = ({ block }: ColumnListProps) => {
1110
if (!block || !block.children) return null;
1211

1312
return (
1413
<div className={columnListContainer}>
15-
{block.children.map((column: any) => (
16-
<Column key={column.id} block={column} onFocus={onFocus} />
14+
{block.children.map((column) => (
15+
<Column key={column.id} block={column} />
1716
))}
1817
</div>
1918
);

packages/notion-to-jsx/src/components/Renderer/components/Image/Image.tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from 'react';
1+
import { useState } from 'react';
22
import { MemoizedRichText } from '../MemoizedComponents';
33
import {
44
imageContainer,
@@ -16,15 +16,6 @@ export interface ImageFormat {
1616
block_aspect_ratio?: number;
1717
}
1818

19-
export interface ImageProps {
20-
src: string;
21-
alt: string;
22-
caption?: RichTextItem[];
23-
priority?: boolean;
24-
format?: ImageFormat;
25-
isColumn?: boolean;
26-
}
27-
2819
const MAX_WIDTH = 720;
2920

3021
// 이미지 태그에 사용되는 aspectRatio 스타일
@@ -34,13 +25,22 @@ const getImageTagStyle = (format?: ImageFormat) => {
3425
: undefined;
3526
};
3627

37-
const Image: React.FC<ImageProps> = ({
28+
export interface Props {
29+
src: string;
30+
alt: string;
31+
caption?: RichTextItem[];
32+
priority?: boolean;
33+
format?: ImageFormat;
34+
isColumn?: boolean;
35+
}
36+
37+
const Image = ({
3838
src,
3939
alt,
4040
caption: imageCaption,
4141
format,
4242
isColumn = false,
43-
}) => {
43+
}: Props) => {
4444
const [isLoaded, setIsLoaded] = useState(false);
4545

4646
return (
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
export { default as Image } from './Image';
2-
export type { ImageProps } from './Image';
2+
export type { Props as ImageProps } from './Image';

0 commit comments

Comments
 (0)