Skip to content

Commit

Permalink
feat: add experimental page link mention support (#145)
Browse files Browse the repository at this point in the history
* feat: add experimental page link mention support

* chore: cleanup

* chore: make icon url optional

* fix: update decorator order, add overrides

* chore: remove logs

---------

Co-authored-by: janniks <janniks@users.noreply.github.com>
  • Loading branch information
janniks and janniks committed Jul 26, 2024
1 parent 49d4b6d commit 1bb5f32
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 10 deletions.
1 change: 1 addition & 0 deletions dev/serve.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export default {
// table tester: bd1de400a8b349dc824f4f00e61d0797
// todo tester: 235057194b954a60ace89c052a65d102
// indent tester: 5b494cf668b04197882fe1b66c6ee2a8
// mention tester: f53ddc084206442098cab6b4fa016d94
this.blockMap = await getPageBlocks("2e22de6b770e4166be301490f6ffd420");
},
};
Expand Down
8 changes: 7 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The `NotionRenderer` component offers a few properties
- [`blockMap`](#blockMap) – required
- [`blockOverrides`](#blockOverrides) – default: `{}`
- [`contentId`](#contentId) – default: `undefined`
- [`decoratorOverrides`](#decoratorOverrides) – default: `{}`
- [`embedAllow`](#embedAllow) – default: `"fullscreen"`
- [`fullPage`](#fullPage) – default: `false`
- [`hideList`](#hideList) – default: `[]`
Expand Down Expand Up @@ -52,6 +53,11 @@ blockOverrides: {
If this is `undefined` the _first_ block is rendered.
_Usually the first block contains the rest of the page._

### `decoratorOverrides`: Object

– the Notion text decorators that should be overriden by custom registered Vue components.
A key-value pair Object of Notion decorator names to Vue component names.

### `embedAllow`: String

– the [`allow` feature policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-allow) for embedded `<iframe>`s (e.g. YouTube videos).
Expand Down Expand Up @@ -223,7 +229,7 @@ There are a few required steps to allow Nuxt to work with vue-notion
// nuxt.config.js
export default {
// ...
buildModules: ["vue-notion/nuxt"]
buildModules: ["vue-notion/nuxt"],
};
```

Expand Down
16 changes: 14 additions & 2 deletions src/blocks/decorator.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
<template>
<component
v-if="isPageLink && hasPageLinkOptions"
v-if="decoratorOverrides.hasOwnProperty(decoratorKey)"
:is="decoratorOverrides[decoratorKey]"
v-bind="pass"
/>
<NotionMention
v-else-if="isPageLink && decoratorKey === 'lm'"
:mention="decoratorValue"
v-bind="pass"
/>
<component
v-else-if="isPageLink && hasPageLinkOptions"
class="notion-link"
v-bind="pageLinkProps(decoratorValue)"
:is="pageLinkOptions.component"
>
{{ pageLinkTitle }}
</component>
<a
v-else-if="isPageLink"
v-else-if="isPageLink && typeof decoratorValue === 'string'"
class="notion-link"
:target="pageLinkTarget"
:href="mapPageUrl(decoratorValue)"
Expand Down Expand Up @@ -67,11 +77,13 @@

<script>
import { Blockable, blockProps } from "@/lib/blockable";
import NotionMention from "@/blocks/helpers/mention";
export default {
extends: Blockable,
name: "NotionDecorator",
props: { ...blockProps, content: Array },
components: { NotionMention },
computed: {
text() {
return this.content?.[0];
Expand Down
23 changes: 23 additions & 0 deletions src/blocks/helpers/mention.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<template>
<a :href="mention.href" class="notion-text-mention">
<img
class="notion-text-mention-icon"
v-if="mention.icon_url"
:src="mention.icon_url"
/>
<span class="notion-text-mention-title">{{ mention.title }}</span>
</a>
</template>

<script>
import { Blockable, blockComputed, blockProps } from "@/lib/blockable";
export default {
extends: Blockable,
name: "NotionMention",
props: { ...blockProps, mention: Object },
computed: {
...blockComputed,
},
};
</script>
1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export { default as NotionColumnSpacer } from "../blocks/helpers/column-spacer.v
export { default as NotionFigure } from "../blocks/helpers/figure.vue";
export { default as NotionFragment } from "../blocks/helpers/fragment.vue";
export { default as NotionImage } from "../blocks/helpers/image.vue";
export { default as NotionMention } from "../blocks/helpers/mention.vue";
export { default as NotionNestedList } from "../blocks/helpers/nested-list.vue";
export { default as NotionPageHeader } from "../blocks/helpers/page-header.vue";
export { default as NotionPageIcon } from "../blocks/helpers/page-icon.vue";
Expand Down
16 changes: 9 additions & 7 deletions src/lib/blockable.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const blockProps = {
blockOverrides: { type: Object, default: () => ({}) },
contentId: { type: String, required: false },
contentIndex: { type: Number, default: 0 },
decoratorOverrides: { type: Object, default: () => ({}) },
embedAllow: { type: String, default: "fullscreen" },
fullPage: { type: Boolean, default: false },
hideList: { type: Array, default: () => [] },
Expand All @@ -17,7 +18,7 @@ export const blockProps = {
pageLinkTarget: { type: String, default: "_self" },
prism: { type: Boolean, default: false },
textLinkTarget: { type: String, default: "_blank" },
todo: { type: Boolean, default: false }
todo: { type: Boolean, default: false },
};

export const blockComputed = {
Expand All @@ -28,6 +29,7 @@ export const blockComputed = {
blockOverrides: this.blockOverrides,
contentId: this.contentId,
contentIndex: this.contentIndex,
decoratorOverrides: this.decoratorOverrides,
embedAllow: this.embedAllow,
fullPage: this.fullPage,
hideList: this.hideList,
Expand All @@ -38,7 +40,7 @@ export const blockComputed = {
mapPageUrl: this.mapPageUrl,
pageLinkOptions: this.pageLinkOptions,
prism: this.prism,
todo: this.todo
todo: this.todo,
};
},
alt() {
Expand All @@ -63,7 +65,7 @@ export const blockComputed = {
block_color: this.format?.block_color,
bookmark_icon: this.format?.bookmark_icon,
bookmark_cover: this.format?.bookmark_cover,
display_source: this.format?.display_source
display_source: this.format?.display_source,
};
},
icon() {
Expand Down Expand Up @@ -98,7 +100,7 @@ export const blockComputed = {
},
parent() {
return this.blockMap[this.value?.parent_id];
}
},
};

export const Blockable = {
Expand All @@ -119,8 +121,8 @@ export const Blockable = {
},
pageLinkProps(id) {
return {
[this.pageLinkOptions?.href || "href"]: this.mapPageUrl(id)
[this.pageLinkOptions?.href || "href"]: this.mapPageUrl(id),
};
}
}
},
},
};
19 changes: 19 additions & 0 deletions src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -726,3 +726,22 @@ img.notion-nav-icon {
flex-direction: column;
padding-left: 1.5em;
}

.notion-text-mention {
text-decoration: none;
}

.notion-text-mention-icon {
padding: 0;
width: 1.2em;
height: 1.2em;
border-radius: 3px;
vertical-align: -0.15em;
margin-right: 0.3em;
}

.notion-text-mention-title {
border-bottom: 0.05em solid solid rgba(55, 55, 55, 1);
font-weight: 500;
flex-shrink: 0;
}

0 comments on commit 1bb5f32

Please sign in to comment.