@@ -3,17 +3,15 @@ import {
3
3
DecorationType ,
4
4
BlockType ,
5
5
ContentValueType ,
6
- BlockMapType
6
+ BlockMapType ,
7
+ MapPageUrl ,
8
+ MapImageUrl
7
9
} from "./types" ;
8
10
import Asset from "./components/asset" ;
9
11
import Code from "./components/code" ;
10
12
import PageIcon from "./components/page-icon" ;
11
- import {
12
- classNames ,
13
- getTextContent ,
14
- getListNumber ,
15
- toNotionImageUrl
16
- } from "./utils" ;
13
+ import PageHeader from "./components/page-header" ;
14
+ import { classNames , getTextContent , getListNumber } from "./utils" ;
17
15
18
16
export const renderChildText = ( properties : DecorationType [ ] ) => {
19
17
return properties ?. map ( ( [ text , decorations ] , i ) => {
@@ -55,20 +53,30 @@ export const renderChildText = (properties: DecorationType[]) => {
55
53
} ) ;
56
54
} ;
57
55
58
- export type MapPageUrl = ( pageId : string ) => string ;
59
-
60
56
interface Block {
61
57
block : BlockType ;
62
58
level : number ;
63
59
blockMap : BlockMapType ;
60
+ mapPageUrl : MapPageUrl ;
61
+ mapImageUrl : MapImageUrl ;
64
62
65
63
fullPage ?: boolean ;
66
- mapPageUrl ?: MapPageUrl ;
64
+ hideHeader ?: boolean ;
67
65
}
68
66
69
67
export const Block : React . FC < Block > = props => {
70
- const { block, children, level, fullPage, blockMap } = props ;
68
+ const {
69
+ block,
70
+ children,
71
+ level,
72
+ fullPage,
73
+ hideHeader,
74
+ blockMap,
75
+ mapPageUrl,
76
+ mapImageUrl
77
+ } = props ;
71
78
const blockValue = block ?. value ;
79
+
72
80
switch ( blockValue ?. type ) {
73
81
case "page" :
74
82
if ( level === 0 ) {
@@ -88,54 +96,68 @@ export const Block: React.FC<Block> = props => {
88
96
const coverPosition = ( 1 - ( page_cover_position || 0.5 ) ) * 100 ;
89
97
90
98
return (
91
- < div className = "notion" >
92
- { page_cover && (
93
- < img
94
- src = { toNotionImageUrl ( page_cover ) }
95
- alt = { getTextContent ( blockValue . properties . title ) }
96
- className = "notion-page-cover"
97
- style = { {
98
- objectPosition : `center ${ coverPosition } %`
99
- } }
100
- />
101
- ) }
102
- < div
103
- className = { classNames (
104
- "notion-page" ,
105
- ! page_cover && "notion-page-offset" ,
106
- page_full_width && "notion-full-width" ,
107
- page_small_text && "notion-small-text"
108
- ) }
109
- >
110
- { page_icon && (
111
- < PageIcon
112
- className = {
113
- page_cover ? "notion-page-icon-offset" : undefined
114
- }
115
- block = { block }
116
- big
117
- />
118
- ) }
119
- < div className = "notion-title" >
120
- { renderChildText ( blockValue . properties . title ) }
99
+ < div className = "notion notion-app" >
100
+ < div className = "notion-cursor-listener" >
101
+ < div className = "notion-frame" >
102
+ { ! hideHeader && (
103
+ < PageHeader
104
+ blockMap = { blockMap }
105
+ mapPageUrl = { mapPageUrl }
106
+ mapImageUrl = { mapImageUrl }
107
+ />
108
+ ) }
109
+
110
+ < div className = "notion-scroller" >
111
+ { page_cover && (
112
+ < img
113
+ src = { mapImageUrl ( page_cover ) }
114
+ alt = { getTextContent ( blockValue . properties . title ) }
115
+ className = "notion-page-cover"
116
+ style = { {
117
+ objectPosition : `center ${ coverPosition } %`
118
+ } }
119
+ />
120
+ ) }
121
+ < main
122
+ className = { classNames (
123
+ "notion-page" ,
124
+ ! page_cover && "notion-page-offset" ,
125
+ page_full_width && "notion-full-width" ,
126
+ page_small_text && "notion-small-text"
127
+ ) }
128
+ >
129
+ { page_icon && (
130
+ < PageIcon
131
+ className = {
132
+ page_cover ? "notion-page-icon-offset" : undefined
133
+ }
134
+ block = { block }
135
+ big
136
+ mapImageUrl = { mapImageUrl }
137
+ />
138
+ ) }
139
+
140
+ < div className = "notion-title" >
141
+ { renderChildText ( blockValue . properties . title ) }
142
+ </ div >
143
+
144
+ { children }
145
+ </ main >
146
+ </ div >
121
147
</ div >
122
- { children }
123
148
</ div >
124
149
</ div >
125
150
) ;
126
151
} else {
127
- return < div className = "notion" > { children } </ div > ;
152
+ return < main className = "notion" > { children } </ main > ;
128
153
}
129
154
} else {
130
155
if ( ! blockValue . properties ) return null ;
131
156
return (
132
- < a
133
- className = "notion-page-link"
134
- href = { props . mapPageUrl ?.( blockValue . id ) || `/${ blockValue . id } ` }
135
- >
157
+ < a className = "notion-page-link" href = { mapPageUrl ( blockValue . id ) } >
136
158
{ blockValue . format && (
137
159
< div className = "notion-page-icon" >
138
- < PageIcon block = { block } />
160
+ < PageIcon block = { block } mapImageUrl = { mapImageUrl } />
139
161
</ div >
140
162
) }
141
163
< div className = "notion-page-text" >
@@ -169,7 +191,7 @@ export const Block: React.FC<Block> = props => {
169
191
return < hr className = "notion-hr" /> ;
170
192
case "text" :
171
193
if ( ! blockValue . properties ) {
172
- return < div className = "notion-blank" / >;
194
+ return < div className = "notion-blank" > </ div > ;
173
195
}
174
196
const blockColor = blockValue . format ?. block_color ;
175
197
return (
@@ -226,7 +248,8 @@ export const Block: React.FC<Block> = props => {
226
248
className = "notion-asset-wrapper"
227
249
style = { { width : value . format . block_width } }
228
250
>
229
- < Asset block = { block } />
251
+ < Asset block = { block } mapImageUrl = { mapImageUrl } />
252
+
230
253
{ value . properties . caption && (
231
254
< figcaption className = "notion-image-caption" >
232
255
{ renderChildText ( value . properties . caption ) }
@@ -269,45 +292,52 @@ export const Block: React.FC<Block> = props => {
269
292
) ;
270
293
case "collection_view" :
271
294
if ( ! block ) return null ;
295
+
272
296
const collectionView = block ?. collection ?. types [ 0 ] ;
273
297
274
298
return (
275
299
< div >
276
300
< h3 className = "notion-h3" >
277
301
{ renderChildText ( block . collection ?. title ! ) }
278
302
</ h3 >
303
+
279
304
{ collectionView ?. type === "table" && (
280
305
< div style = { { maxWidth : "100%" , marginTop : 5 } } >
281
306
< table className = "notion-table" >
282
307
< thead >
283
308
< tr className = "notion-tr" >
284
309
{ collectionView . format ?. table_properties
285
310
?. filter ( p => p . visible )
286
- . map ( gp => (
311
+ . map ( ( gp , index ) => (
287
312
< th
288
313
className = "notion-th"
314
+ key = { index }
289
315
style = { { minWidth : gp . width } }
290
316
>
291
- { block . collection ?. schema [ gp . property ] . name }
317
+ { block . collection ?. schema [ gp . property ] ? .name }
292
318
</ th >
293
319
) ) }
294
320
</ tr >
295
321
</ thead >
322
+
296
323
< tbody >
297
- { block ?. collection ?. data . map ( row => (
298
- < tr className = "notion-tr" >
324
+ { block ?. collection ?. data . map ( ( row , index ) => (
325
+ < tr className = "notion-tr" key = { index } >
299
326
{ collectionView . format ?. table_properties
300
327
?. filter ( p => p . visible )
301
- . map ( gp => (
328
+ . map ( ( gp , index ) => (
302
329
< td
330
+ key = { index }
303
331
className = {
304
332
"notion-td " +
305
333
( gp . property === "title" ? "notion-bold" : "" )
306
334
}
307
335
>
308
336
{
309
337
renderChildText (
310
- row [ block . collection ?. schema [ gp . property ] . name ! ]
338
+ row [
339
+ block . collection ?. schema [ gp . property ] ?. name !
340
+ ]
311
341
) !
312
342
}
313
343
</ td >
@@ -318,6 +348,7 @@ export const Block: React.FC<Block> = props => {
318
348
</ table >
319
349
</ div >
320
350
) }
351
+
321
352
{ collectionView ?. type === "gallery" && (
322
353
< div className = "notion-gallery" >
323
354
{ block . collection ?. data . map ( ( row , i ) => (
@@ -355,7 +386,7 @@ export const Block: React.FC<Block> = props => {
355
386
) }
356
387
>
357
388
< div >
358
- < PageIcon block = { block } />
389
+ < PageIcon block = { block } mapImageUrl = { mapImageUrl } />
359
390
</ div >
360
391
< div className = "notion-callout-text" >
361
392
{ renderChildText ( blockValue . properties . title ) }
0 commit comments