@@ -3,17 +3,15 @@ import {
33 DecorationType ,
44 BlockType ,
55 ContentValueType ,
6- BlockMapType
6+ BlockMapType ,
7+ MapPageUrl ,
8+ MapImageUrl
79} from "./types" ;
810import Asset from "./components/asset" ;
911import Code from "./components/code" ;
1012import 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" ;
1715
1816export const renderChildText = ( properties : DecorationType [ ] ) => {
1917 return properties ?. map ( ( [ text , decorations ] , i ) => {
@@ -55,20 +53,30 @@ export const renderChildText = (properties: DecorationType[]) => {
5553 } ) ;
5654} ;
5755
58- export type MapPageUrl = ( pageId : string ) => string ;
59-
6056interface Block {
6157 block : BlockType ;
6258 level : number ;
6359 blockMap : BlockMapType ;
60+ mapPageUrl : MapPageUrl ;
61+ mapImageUrl : MapImageUrl ;
6462
6563 fullPage ?: boolean ;
66- mapPageUrl ?: MapPageUrl ;
64+ hideHeader ?: boolean ;
6765}
6866
6967export 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 ;
7178 const blockValue = block ?. value ;
79+
7280 switch ( blockValue ?. type ) {
7381 case "page" :
7482 if ( level === 0 ) {
@@ -88,54 +96,68 @@ export const Block: React.FC<Block> = props => {
8896 const coverPosition = ( 1 - ( page_cover_position || 0.5 ) ) * 100 ;
8997
9098 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 >
121147 </ div >
122- { children }
123148 </ div >
124149 </ div >
125150 ) ;
126151 } else {
127- return < div className = "notion" > { children } </ div > ;
152+ return < main className = "notion" > { children } </ main > ;
128153 }
129154 } else {
130155 if ( ! blockValue . properties ) return null ;
131156 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 ) } >
136158 { blockValue . format && (
137159 < div className = "notion-page-icon" >
138- < PageIcon block = { block } />
160+ < PageIcon block = { block } mapImageUrl = { mapImageUrl } />
139161 </ div >
140162 ) }
141163 < div className = "notion-page-text" >
@@ -169,7 +191,7 @@ export const Block: React.FC<Block> = props => {
169191 return < hr className = "notion-hr" /> ;
170192 case "text" :
171193 if ( ! blockValue . properties ) {
172- return < div className = "notion-blank" / >;
194+ return < div className = "notion-blank" > </ div > ;
173195 }
174196 const blockColor = blockValue . format ?. block_color ;
175197 return (
@@ -226,7 +248,8 @@ export const Block: React.FC<Block> = props => {
226248 className = "notion-asset-wrapper"
227249 style = { { width : value . format . block_width } }
228250 >
229- < Asset block = { block } />
251+ < Asset block = { block } mapImageUrl = { mapImageUrl } />
252+
230253 { value . properties . caption && (
231254 < figcaption className = "notion-image-caption" >
232255 { renderChildText ( value . properties . caption ) }
@@ -269,45 +292,52 @@ export const Block: React.FC<Block> = props => {
269292 ) ;
270293 case "collection_view" :
271294 if ( ! block ) return null ;
295+
272296 const collectionView = block ?. collection ?. types [ 0 ] ;
273297
274298 return (
275299 < div >
276300 < h3 className = "notion-h3" >
277301 { renderChildText ( block . collection ?. title ! ) }
278302 </ h3 >
303+
279304 { collectionView ?. type === "table" && (
280305 < div style = { { maxWidth : "100%" , marginTop : 5 } } >
281306 < table className = "notion-table" >
282307 < thead >
283308 < tr className = "notion-tr" >
284309 { collectionView . format ?. table_properties
285310 ?. filter ( p => p . visible )
286- . map ( gp => (
311+ . map ( ( gp , index ) => (
287312 < th
288313 className = "notion-th"
314+ key = { index }
289315 style = { { minWidth : gp . width } }
290316 >
291- { block . collection ?. schema [ gp . property ] . name }
317+ { block . collection ?. schema [ gp . property ] ? .name }
292318 </ th >
293319 ) ) }
294320 </ tr >
295321 </ thead >
322+
296323 < 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 } >
299326 { collectionView . format ?. table_properties
300327 ?. filter ( p => p . visible )
301- . map ( gp => (
328+ . map ( ( gp , index ) => (
302329 < td
330+ key = { index }
303331 className = {
304332 "notion-td " +
305333 ( gp . property === "title" ? "notion-bold" : "" )
306334 }
307335 >
308336 {
309337 renderChildText (
310- row [ block . collection ?. schema [ gp . property ] . name ! ]
338+ row [
339+ block . collection ?. schema [ gp . property ] ?. name !
340+ ]
311341 ) !
312342 }
313343 </ td >
@@ -318,6 +348,7 @@ export const Block: React.FC<Block> = props => {
318348 </ table >
319349 </ div >
320350 ) }
351+
321352 { collectionView ?. type === "gallery" && (
322353 < div className = "notion-gallery" >
323354 { block . collection ?. data . map ( ( row , i ) => (
@@ -355,7 +386,7 @@ export const Block: React.FC<Block> = props => {
355386 ) }
356387 >
357388 < div >
358- < PageIcon block = { block } />
389+ < PageIcon block = { block } mapImageUrl = { mapImageUrl } />
359390 </ div >
360391 < div className = "notion-callout-text" >
361392 { renderChildText ( blockValue . properties . title ) }
0 commit comments