Skip to content

Commit 68f80b6

Browse files
committed
refactor: Bookmark migration
1 parent f621d23 commit 68f80b6

File tree

6 files changed

+111
-157
lines changed

6 files changed

+111
-157
lines changed

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

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,18 +88,8 @@ const BlockRenderer: React.FC<Props> = ({ block, onFocus, index }) => {
8888
</figure>
8989
);
9090

91-
// case 'bookmark':
92-
// return (
93-
// <BookmarkCard {...blockProps}>
94-
// <BookmarkLink
95-
// href={block.bookmark.url}
96-
// target="_blank"
97-
// rel="noopener noreferrer"
98-
// >
99-
// <MemoizedBookmark url={block.bookmark.url} />
100-
// </BookmarkLink>
101-
// </BookmarkCard>
102-
// );
91+
case 'bookmark':
92+
return <MemoizedBookmark url={block.bookmark.url} />;
10393

10494
default:
10595
return null;

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

Lines changed: 51 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
import React, { useState, useEffect } from 'react';
2-
import styled from 'styled-components';
32
import { type RichTextItem } from '../../../../types';
4-
import RichTexts from '../RichText/RichTexts';
3+
import { MemoizedRichText } from '../MemoizedComponents';
4+
import {
5+
link,
6+
card,
7+
content,
8+
previewImage,
9+
title,
10+
description,
11+
siteName,
12+
caption,
13+
} from './styles.css';
514

615
interface OpenGraphData {
716
title: string;
@@ -15,68 +24,28 @@ export interface BookmarkProps {
1524
caption?: RichTextItem[];
1625
}
1726

18-
const Card = styled.div`
19-
margin: ${({ theme }) => theme.spacing.md} 0;
20-
border: 1px solid ${({ theme }) => theme.colors.border};
21-
border-radius: ${({ theme }) => theme.borderRadius.md};
22-
overflow: hidden;
23-
transition: box-shadow 0.2s ease;
24-
25-
&:hover {
26-
box-shadow: ${({ theme }) => theme.shadows.md};
27-
}
28-
`;
29-
30-
const Content = styled.div`
31-
padding: ${({ theme }) => theme.spacing.md};
32-
`;
33-
34-
const PreviewImage = styled.img`
35-
width: 100%;
36-
height: 200px;
37-
object-fit: cover;
38-
background: ${({ theme }) => theme.colors.code.background};
39-
`;
40-
41-
const Title = styled.h4`
42-
margin: 0 0 ${({ theme }) => theme.spacing.xs};
43-
font-size: ${({ theme }) => theme.typography.fontSize.base};
44-
color: ${({ theme }) => theme.colors.text};
45-
`;
46-
47-
const Description = styled.p`
48-
margin: 0;
49-
font-size: ${({ theme }) => theme.typography.fontSize.small};
50-
color: ${({ theme }) => theme.colors.secondary};
51-
display: -webkit-box;
52-
-webkit-line-clamp: 2;
53-
-webkit-box-orient: vertical;
54-
overflow: hidden;
55-
`;
56-
57-
const SiteName = styled.div`
58-
margin-top: ${({ theme }) => theme.spacing.sm};
59-
font-size: ${({ theme }) => theme.typography.fontSize.small};
60-
color: ${({ theme }) => theme.colors.primary};
61-
`;
62-
63-
const Caption = styled.div`
64-
margin-top: ${({ theme }) => theme.spacing.sm};
65-
padding-top: ${({ theme }) => theme.spacing.sm};
66-
border-top: 1px solid ${({ theme }) => theme.colors.border};
67-
font-size: ${({ theme }) => theme.typography.fontSize.small};
68-
color: ${({ theme }) => theme.colors.secondary};
69-
`;
70-
7127
// 실제 프로덕션에서는 서버 사이드에서 처리하거나 전용 API를 사용해야 합니다
7228
const fetchOpenGraphData = async (url: string): Promise<OpenGraphData> => {
73-
// 임시로 더미 데이터를 반환
74-
return {
75-
title: new URL(url).hostname,
76-
description: 'No description available',
77-
image: '',
78-
siteName: new URL(url).hostname.split('.')[1] as string,
79-
};
29+
try {
30+
const parsedUrl = new URL(url);
31+
const domain = parsedUrl.hostname;
32+
const siteName = domain.split('.')[1] || domain;
33+
34+
// 임시로 더미 데이터를 반환
35+
return {
36+
title: domain,
37+
description: 'No description available',
38+
image: '',
39+
siteName: siteName,
40+
};
41+
} catch {
42+
return {
43+
title: url,
44+
description: 'Invalid URL',
45+
image: '',
46+
siteName: 'Unknown',
47+
};
48+
}
8049
};
8150

8251
const Bookmark: React.FC<BookmarkProps> = ({ url, caption }) => {
@@ -97,29 +66,31 @@ const Bookmark: React.FC<BookmarkProps> = ({ url, caption }) => {
9766
}, [url]);
9867

9968
return (
100-
<a
101-
href={url}
102-
target="_blank"
103-
rel="noopener noreferrer"
104-
style={{ textDecoration: 'none' }}
105-
>
106-
<Card>
69+
<a href={url} target="_blank" rel="noopener noreferrer" className={link}>
70+
<div className={card}>
10771
{ogData?.image && (
108-
<PreviewImage src={ogData.image} alt={ogData.title} loading="lazy" />
72+
<img
73+
className={previewImage}
74+
src={ogData.image}
75+
alt={ogData.title}
76+
loading="lazy"
77+
/>
10978
)}
110-
<Content>
111-
<Title>{ogData?.title || url}</Title>
79+
<div className={content}>
80+
<h4 className={title}>{ogData?.title || url}</h4>
11281
{ogData?.description && (
113-
<Description>{ogData.description}</Description>
82+
<p className={description}>{ogData.description}</p>
11483
)}
115-
{ogData?.siteName && <SiteName>{ogData.siteName}</SiteName>}
116-
{caption && caption.length > 0 && (
117-
<Caption>
118-
<RichTexts richTexts={caption} />
119-
</Caption>
84+
{ogData?.siteName && (
85+
<div className={siteName}>{ogData.siteName}</div>
12086
)}
121-
</Content>
122-
</Card>
87+
{/* {caption && caption.length > 0 && (
88+
<div className={caption}>
89+
<MemoizedRichText richTexts={caption} />
90+
</div>
91+
)} */}
92+
</div>
93+
</div>
12394
</a>
12495
);
12596
};
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { style } from '@vanilla-extract/css';
2+
import { vars } from '../../../../styles/theme.css';
3+
4+
export const link = style({
5+
textDecoration: 'none',
6+
});
7+
8+
export const card = style({
9+
margin: `${vars.spacing.md} 0`,
10+
border: `1px solid ${vars.colors.border}`,
11+
borderRadius: vars.borderRadius.md,
12+
overflow: 'hidden',
13+
transition: 'box-shadow 0.2s ease',
14+
':hover': {
15+
boxShadow: vars.shadows.md,
16+
},
17+
});
18+
19+
export const content = style({
20+
padding: vars.spacing.md,
21+
});
22+
23+
export const previewImage = style({
24+
width: '100%',
25+
height: '200px',
26+
objectFit: 'cover',
27+
background: vars.colors.code.background,
28+
});
29+
30+
export const title = style({
31+
margin: `0 0 ${vars.spacing.xs}`,
32+
fontSize: vars.typography.fontSize.base,
33+
color: vars.colors.text,
34+
});
35+
36+
export const description = style({
37+
margin: 0,
38+
fontSize: vars.typography.fontSize.small,
39+
color: vars.colors.secondary,
40+
display: '-webkit-box',
41+
WebkitLineClamp: 2,
42+
WebkitBoxOrient: 'vertical',
43+
overflow: 'hidden',
44+
});
45+
46+
export const siteName = style({
47+
marginTop: vars.spacing.sm,
48+
fontSize: vars.typography.fontSize.small,
49+
color: vars.colors.primary,
50+
});
51+
52+
export const caption = style({
53+
marginTop: vars.spacing.sm,
54+
paddingTop: vars.spacing.sm,
55+
borderTop: `1px solid ${vars.colors.border}`,
56+
fontSize: vars.typography.fontSize.small,
57+
color: vars.colors.secondary,
58+
});

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

Lines changed: 0 additions & 37 deletions
This file was deleted.

packages/notion-to-jsx/src/components/Renderer/components/Media/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

packages/notion-to-jsx/src/components/Renderer/components/Media/styles.css.ts

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)