Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 1bb5f32

Browse files
authored
feat: add experimental page link mention support (#145)
* 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>
1 parent 49d4b6d commit 1bb5f32

File tree

7 files changed

+74
-10
lines changed

7 files changed

+74
-10
lines changed

‎dev/serve.vue‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default {
2626
// table tester: bd1de400a8b349dc824f4f00e61d0797
2727
// todo tester: 235057194b954a60ace89c052a65d102
2828
// indent tester: 5b494cf668b04197882fe1b66c6ee2a8
29+
// mention tester: f53ddc084206442098cab6b4fa016d94
2930
this.blockMap = await getPageBlocks("2e22de6b770e4166be301490f6ffd420");
3031
},
3132
};

‎docs/README.md‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ The `NotionRenderer` component offers a few properties
1616
- [`blockMap`](#blockMap) – required
1717
- [`blockOverrides`](#blockOverrides) – default: `{}`
1818
- [`contentId`](#contentId) – default: `undefined`
19+
- [`decoratorOverrides`](#decoratorOverrides) – default: `{}`
1920
- [`embedAllow`](#embedAllow) – default: `"fullscreen"`
2021
- [`fullPage`](#fullPage) – default: `false`
2122
- [`hideList`](#hideList) – default: `[]`
@@ -52,6 +53,11 @@ blockOverrides: {
5253
If this is `undefined` the _first_ block is rendered.
5354
_Usually the first block contains the rest of the page._
5455

56+
### `decoratorOverrides`: Object
57+
58+
– the Notion text decorators that should be overriden by custom registered Vue components.
59+
A key-value pair Object of Notion decorator names to Vue component names.
60+
5561
### `embedAllow`: String
5662

5763
– 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).
@@ -223,7 +229,7 @@ There are a few required steps to allow Nuxt to work with vue-notion
223229
// nuxt.config.js
224230
export default {
225231
// ...
226-
buildModules: ["vue-notion/nuxt"]
232+
buildModules: ["vue-notion/nuxt"],
227233
};
228234
```
229235

‎src/blocks/decorator.vue‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
<template>
22
<component
3-
v-if="isPageLink && hasPageLinkOptions"
3+
v-if="decoratorOverrides.hasOwnProperty(decoratorKey)"
4+
:is="decoratorOverrides[decoratorKey]"
5+
v-bind="pass"
6+
/>
7+
<NotionMention
8+
v-else-if="isPageLink && decoratorKey === 'lm'"
9+
:mention="decoratorValue"
10+
v-bind="pass"
11+
/>
12+
<component
13+
v-else-if="isPageLink && hasPageLinkOptions"
414
class="notion-link"
515
v-bind="pageLinkProps(decoratorValue)"
616
:is="pageLinkOptions.component"
717
>
818
{{ pageLinkTitle }}
919
</component>
1020
<a
11-
v-else-if="isPageLink"
21+
v-else-if="isPageLink && typeof decoratorValue === 'string'"
1222
class="notion-link"
1323
:target="pageLinkTarget"
1424
:href="mapPageUrl(decoratorValue)"
@@ -67,11 +77,13 @@
6777

6878
<script>
6979
import { Blockable, blockProps } from "@/lib/blockable";
80+
import NotionMention from "@/blocks/helpers/mention";
7081
7182
export default {
7283
extends: Blockable,
7384
name: "NotionDecorator",
7485
props: { ...blockProps, content: Array },
86+
components: { NotionMention },
7587
computed: {
7688
text() {
7789
return this.content?.[0];

‎src/blocks/helpers/mention.vue‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<template>
2+
<a :href="mention.href" class="notion-text-mention">
3+
<img
4+
class="notion-text-mention-icon"
5+
v-if="mention.icon_url"
6+
:src="mention.icon_url"
7+
/>
8+
<span class="notion-text-mention-title">{{ mention.title }}</span>
9+
</a>
10+
</template>
11+
12+
<script>
13+
import { Blockable, blockComputed, blockProps } from "@/lib/blockable";
14+
15+
export default {
16+
extends: Blockable,
17+
name: "NotionMention",
18+
props: { ...blockProps, mention: Object },
19+
computed: {
20+
...blockComputed,
21+
},
22+
};
23+
</script>

‎src/components/index.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export { default as NotionColumnSpacer } from "../blocks/helpers/column-spacer.v
2222
export { default as NotionFigure } from "../blocks/helpers/figure.vue";
2323
export { default as NotionFragment } from "../blocks/helpers/fragment.vue";
2424
export { default as NotionImage } from "../blocks/helpers/image.vue";
25+
export { default as NotionMention } from "../blocks/helpers/mention.vue";
2526
export { default as NotionNestedList } from "../blocks/helpers/nested-list.vue";
2627
export { default as NotionPageHeader } from "../blocks/helpers/page-header.vue";
2728
export { default as NotionPageIcon } from "../blocks/helpers/page-icon.vue";

‎src/lib/blockable.js‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export const blockProps = {
55
blockOverrides: { type: Object, default: () => ({}) },
66
contentId: { type: String, required: false },
77
contentIndex: { type: Number, default: 0 },
8+
decoratorOverrides: { type: Object, default: () => ({}) },
89
embedAllow: { type: String, default: "fullscreen" },
910
fullPage: { type: Boolean, default: false },
1011
hideList: { type: Array, default: () => [] },
@@ -17,7 +18,7 @@ export const blockProps = {
1718
pageLinkTarget: { type: String, default: "_self" },
1819
prism: { type: Boolean, default: false },
1920
textLinkTarget: { type: String, default: "_blank" },
20-
todo: { type: Boolean, default: false }
21+
todo: { type: Boolean, default: false },
2122
};
2223

2324
export const blockComputed = {
@@ -28,6 +29,7 @@ export const blockComputed = {
2829
blockOverrides: this.blockOverrides,
2930
contentId: this.contentId,
3031
contentIndex: this.contentIndex,
32+
decoratorOverrides: this.decoratorOverrides,
3133
embedAllow: this.embedAllow,
3234
fullPage: this.fullPage,
3335
hideList: this.hideList,
@@ -38,7 +40,7 @@ export const blockComputed = {
3840
mapPageUrl: this.mapPageUrl,
3941
pageLinkOptions: this.pageLinkOptions,
4042
prism: this.prism,
41-
todo: this.todo
43+
todo: this.todo,
4244
};
4345
},
4446
alt() {
@@ -63,7 +65,7 @@ export const blockComputed = {
6365
block_color: this.format?.block_color,
6466
bookmark_icon: this.format?.bookmark_icon,
6567
bookmark_cover: this.format?.bookmark_cover,
66-
display_source: this.format?.display_source
68+
display_source: this.format?.display_source,
6769
};
6870
},
6971
icon() {
@@ -98,7 +100,7 @@ export const blockComputed = {
98100
},
99101
parent() {
100102
return this.blockMap[this.value?.parent_id];
101-
}
103+
},
102104
};
103105

104106
export const Blockable = {
@@ -119,8 +121,8 @@ export const Blockable = {
119121
},
120122
pageLinkProps(id) {
121123
return {
122-
[this.pageLinkOptions?.href || "href"]: this.mapPageUrl(id)
124+
[this.pageLinkOptions?.href || "href"]: this.mapPageUrl(id),
123125
};
124-
}
125-
}
126+
},
127+
},
126128
};

‎src/styles.css‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,3 +726,22 @@ img.notion-nav-icon {
726726
flex-direction: column;
727727
padding-left: 1.5em;
728728
}
729+
730+
.notion-text-mention {
731+
text-decoration: none;
732+
}
733+
734+
.notion-text-mention-icon {
735+
padding: 0;
736+
width: 1.2em;
737+
height: 1.2em;
738+
border-radius: 3px;
739+
vertical-align: -0.15em;
740+
margin-right: 0.3em;
741+
}
742+
743+
.notion-text-mention-title {
744+
border-bottom: 0.05em solid solid rgba(55, 55, 55, 1);
745+
font-weight: 500;
746+
flex-shrink: 0;
747+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /