Skip to content

Fix page link and render line break #40

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 43 additions & 20 deletions src/block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,22 @@ import { classNames, getTextContent, getListNumber } from "./utils";

export const createRenderChildText = (
customDecoratorComponents?: CustomDecoratorComponents
) => (properties: DecorationType[]) => {
) => (properties: DecorationType[], blocks: BlockMapType) => {
return properties?.map(([text, decorations], i) => {
if (!decorations) {
return <React.Fragment key={i}>{text}</React.Fragment>;
return (
<React.Fragment key={i}>
{text.split(/(\n)/).map((t, index) => (
<React.Fragment key={index}>
{t !== "\n" ? t : <br />}
</React.Fragment>
))}
</React.Fragment>
);
Comment on lines +26 to +33
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks a bit hacky, should we wrap it inside span and use innerHTML?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

if (text === "‣" && decorations[0][0] === "p") {
text = blocks[decorations[0][1]]?.value?.properties?.title ?? "";
Comment on lines +36 to +37
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I add blocks param so we could map page title here, and since we only use blockMap, it's not possible to map user mention to username

}

return decorations.reduceRight((element, decorator) => {
Expand Down Expand Up @@ -52,6 +64,12 @@ export const createRenderChildText = (
{element}
</a>
);
case "p":
return (
Copy link
Author

@tdloi tdloi Nov 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking of adding some hooks here to allow changing page url, what do you think @timolins?
For example:

const pageUrl = hooks?.setPageUrl?.(decorator[1]) ?? decorator[1];
return (
    <a className="notion-link" href={pageUrl} key={i}>
    {element}
    </a>
);

This is useful for those want to map pageId to slug (me 😄 ):

      hooks={{
        setPageUrl: (pageId) => props.postsIndex?.[pageId] ?? pageId,
      }}

Some hooks I could think of:

  • setLinkUrl: So you could extract block Id to add in page link
  • setPageUrl: Change page url in case of using slug
  • setBlockAttributes (not implemented): Add id attribute for a block so in page link could work, this also allow us to set id for block which has a link in page pointed to only, avoiding adding a bunch of id which will increase HTML file size by a lot. Could also use for foot notes.

<a className="notion-link" href={decorator[1]} key={i}>
{element}
</a>
);

default:
return <React.Fragment key={i}>{element}</React.Fragment>;
Expand Down Expand Up @@ -171,7 +189,7 @@ export const Block: React.FC<Block> = props => {
)}

<div className="notion-title">
{renderChildText(blockValue.properties.title)}
{renderChildText(blockValue.properties.title, blockMap)}
</div>

{children}
Expand All @@ -191,7 +209,7 @@ export const Block: React.FC<Block> = props => {
</div>
)}
<div className="notion-page-text">
{renderChildText(blockValue.properties.title)}
{renderChildText(blockValue.properties.title, blockMap)}
</div>
</a>
);
Expand All @@ -200,21 +218,21 @@ export const Block: React.FC<Block> = props => {
if (!blockValue.properties) return null;
return (
<h1 className="notion-h1">
{renderChildText(blockValue.properties.title)}
{renderChildText(blockValue.properties.title, blockMap)}
</h1>
);
case "sub_header":
if (!blockValue.properties) return null;
return (
<h2 className="notion-h2">
{renderChildText(blockValue.properties.title)}
{renderChildText(blockValue.properties.title, blockMap)}
</h2>
);
case "sub_sub_header":
if (!blockValue.properties) return null;
return (
<h3 className="notion-h3">
{renderChildText(blockValue.properties.title)}
{renderChildText(blockValue.properties.title, blockMap)}
</h3>
);
case "divider":
Expand All @@ -231,7 +249,7 @@ export const Block: React.FC<Block> = props => {
blockColor && `notion-${blockColor}`
)}
>
{renderChildText(blockValue.properties.title)}
{renderChildText(blockValue.properties.title, blockMap)}
</p>
);
case "bulleted_list":
Expand All @@ -251,14 +269,16 @@ export const Block: React.FC<Block> = props => {
output = (
<>
{blockValue.properties && (
<li>{renderChildText(blockValue.properties.title)}</li>
<li>
{renderChildText(blockValue.properties.title, blockMap)}
</li>
)}
{wrapList(children)}
</>
);
} else {
output = blockValue.properties ? (
<li>{renderChildText(blockValue.properties.title)}</li>
<li>{renderChildText(blockValue.properties.title, blockMap)}</li>
) : null;
}

Expand Down Expand Up @@ -287,13 +307,13 @@ export const Block: React.FC<Block> = props => {

{value.properties.caption && (
<figcaption className="notion-image-caption">
{renderChildText(value.properties.caption)}
{renderChildText(value.properties.caption, blockMap)}
</figcaption>
)}
</figure>
);
case "code": {
if (blockValue.properties.title) {
if ((blockValue.properties.title, blockMap)) {
const content = blockValue.properties.title[0][0];
const language = blockValue.properties.language[0][0];
return (
Expand Down Expand Up @@ -326,7 +346,7 @@ export const Block: React.FC<Block> = props => {
if (!blockValue.properties) return null;
return (
<blockquote className="notion-quote">
{renderChildText(blockValue.properties.title)}
{renderChildText(blockValue.properties.title, blockMap)}
</blockquote>
);
case "collection_view":
Expand All @@ -337,7 +357,7 @@ export const Block: React.FC<Block> = props => {
return (
<div>
<h3 className="notion-h3">
{renderChildText(block.collection?.title!)}
{renderChildText(block.collection?.title!, blockMap)}
</h3>

{collectionView?.type === "table" && (
Expand Down Expand Up @@ -376,7 +396,8 @@ export const Block: React.FC<Block> = props => {
renderChildText(
row[
block.collection?.schema[gp.property]?.name!
]
],
blockMap
)!
}
</td>
Expand Down Expand Up @@ -428,7 +449,7 @@ export const Block: React.FC<Block> = props => {
<PageIcon block={block} mapImageUrl={mapImageUrl} />
</div>
<div className="notion-callout-text">
{renderChildText(blockValue.properties.title)}
{renderChildText(blockValue.properties.title, blockMap)}
</div>
</div>
);
Expand All @@ -453,19 +474,19 @@ export const Block: React.FC<Block> = props => {
>
<div>
<div className="notion-bookmark-title">
{renderChildText(title)}
{renderChildText(title, blockMap)}
</div>
{description && (
<div className="notion-bookmark-description">
{renderChildText(description)}
{renderChildText(description, blockMap)}
</div>
)}

<div className="notion-bookmark-link">
{bookmark_icon && (
<img src={bookmark_icon} alt={getTextContent(title)} />
)}
<div>{renderChildText(link)}</div>
<div>{renderChildText(link, blockMap)}</div>
</div>
</div>
{bookmark_cover && (
Expand All @@ -479,7 +500,9 @@ export const Block: React.FC<Block> = props => {
case "toggle":
return (
<details className="notion-toggle">
<summary>{renderChildText(blockValue.properties.title)}</summary>
<summary>
{renderChildText(blockValue.properties.title, blockMap)}
</summary>
<div>{children}</div>
</details>
);
Expand Down