11import * as React from "react" ;
2- import { DecorationType , BlockType , ContentValueType } from "./types" ;
2+ import {
3+ DecorationType ,
4+ BlockType ,
5+ ContentValueType ,
6+ BlockMapType
7+ } from "./types" ;
38import Asset from "./components/asset" ;
49import Code from "./components/code" ;
5- import { classNames , getTextContent } from "./utils" ;
10+ import PageIcon from "./components/page-icon" ;
11+ import {
12+ classNames ,
13+ getTextContent ,
14+ getListNumber ,
15+ toNotionImageUrl
16+ } from "./utils" ;
617
718export const renderChildText = ( properties : DecorationType [ ] ) => {
819 return properties ?. map ( ( [ text , decorations ] , i ) => {
@@ -49,17 +60,73 @@ export type MapPageUrl = (pageId: string) => string;
4960interface Block {
5061 block : BlockType ;
5162 level : number ;
52- listNumber ?: number ;
63+ blockMap : BlockMapType ;
64+
65+ fullPage ?: boolean ;
5366 mapPageUrl ?: MapPageUrl ;
5467}
5568
5669export const Block : React . FC < Block > = props => {
57- const { block, children, listNumber , level } = props ;
70+ const { block, children, level , fullPage , blockMap } = props ;
5871 const blockValue = block ?. value ;
5972 switch ( blockValue ?. type ) {
6073 case "page" :
61- if ( level === 0 ) return < div className = "notion" > { children } </ div > ;
62- else {
74+ if ( level === 0 ) {
75+ if ( fullPage ) {
76+ if ( ! blockValue . properties ) {
77+ return null ;
78+ }
79+
80+ const {
81+ page_icon,
82+ page_cover,
83+ page_cover_position,
84+ page_full_width,
85+ page_small_text
86+ } = blockValue . format || { } ;
87+
88+ const coverPosition = ( 1 - ( page_cover_position || 0.5 ) ) * 100 ;
89+
90+ 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 ) }
121+ </ div >
122+ { children }
123+ </ div >
124+ </ div >
125+ ) ;
126+ } else {
127+ return < div className = "notion" > { children } </ div > ;
128+ }
129+ } else {
63130 if ( ! blockValue . properties ) return null ;
64131 return (
65132 < a
@@ -68,7 +135,7 @@ export const Block: React.FC<Block> = props => {
68135 >
69136 { blockValue . format && (
70137 < div className = "notion-page-icon" >
71- { blockValue . format . page_icon }
138+ < PageIcon block = { block } />
72139 </ div >
73140 ) }
74141 < div className = "notion-page-text" >
@@ -102,10 +169,16 @@ export const Block: React.FC<Block> = props => {
102169 return < hr className = "notion-hr" /> ;
103170 case "text" :
104171 if ( ! blockValue . properties ) {
105- return < p style = { { height : "1rem" } } > </ p > ;
172+ return < div className = "notion-blank" / >;
106173 }
174+ const blockColor = blockValue . format ?. block_color ;
107175 return (
108- < p className = { `notion-text` } >
176+ < p
177+ className = { classNames (
178+ `notion-text` ,
179+ blockColor && `notion-${ blockColor } `
180+ ) }
181+ >
109182 { renderChildText ( blockValue . properties . title ) }
110183 </ p >
111184 ) ;
@@ -137,7 +210,11 @@ export const Block: React.FC<Block> = props => {
137210 ) : null ;
138211 }
139212
140- return listNumber !== undefined ? wrapList ( output , listNumber ) : output ;
213+ const isTopLevel =
214+ block . value . type !== blockMap [ block . value . parent_id ] . value . type ;
215+ const start = getListNumber ( blockValue . id , blockMap ) ;
216+
217+ return isTopLevel ? wrapList ( output , start ) : output ;
141218
142219 case "image" :
143220 case "embed" :
@@ -199,7 +276,9 @@ export const Block: React.FC<Block> = props => {
199276 `notion-${ blockValue . format . block_color } _co`
200277 ) }
201278 >
202- < div > { blockValue . format . page_icon } </ div >
279+ < div >
280+ < PageIcon block = { block } />
281+ </ div >
203282 < div className = "notion-callout-text" >
204283 { renderChildText ( blockValue . properties . title ) }
205284 </ div >
0 commit comments