Skip to content

Commit bd09ce7

Browse files
authored
Merge pull request #77 from janniks/cleanup-imageoptions
Cleanup options api
2 parents 60b22d7 + 6a99a10 commit bd09ce7

File tree

3 files changed

+67
-39
lines changed

3 files changed

+67
-39
lines changed

docs/README.md

+21-13
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ The `NotionRenderer` component offers a few properties
1818
- [`embedAllow`](#embedAllow) – default: `"fullscreen"`
1919
- [`fullPage`](#fullPage) – default: `false`
2020
- [`hideList`](#hideList) – default: `[]`
21+
- [`imageOptions`](#imageOptions) – default: `undefined`
2122
- [`mapImageUrl`](#mapImageUrl) – default: `defaultMapImageUrl()`
2223
- [`mapPageUrl`](#mapPageUrl) – default: `defaultMapPageUrl()`
2324
- [`pageLinkOptions`](#pageLinkOptions) – default: `undefined`
@@ -50,6 +51,23 @@ The default allows embeds to enter fullscreen.
5051

5152
– a list of Notion blocks (e.g. `"callout"`) that should not be rendered.
5253

54+
### `imageOptions`: Object
55+
56+
– are used to override default image rendering.
57+
`imageOptions` is an `Object` that requires a `component` parameter.
58+
The `src` attribute is optional and defaults to `src`.
59+
Any additional key value pairs are spread onto the component as element attributes.
60+
61+
e.g. to use `nuxt-img` components instead of HTML `img` elements
62+
63+
```js
64+
imageOptions: {
65+
component: "nuxt-img",
66+
"some-attribute": "vue-notion-attr",
67+
// src: 'src', // (default) can be overridden to customize the key of the `src` attribute
68+
}
69+
```
70+
5371
### `mapImageUrl`: Function
5472

5573
– a function that receives `(imageUrl: String, block: Object)` and returns a `url: String` that should be used during rendering.
@@ -74,7 +92,8 @@ mapPageUrl(pageId = "") {
7492
### `pageLinkOptions`: Object
7593

7694
– are used to override links to other Notion pages with custom Vue components.
77-
`pageLinkOptions` is an `Object` that requires a `component` and a `href` parameter.
95+
`pageLinkOptions` is an `Object` that requires a `component` parameter.
96+
The `href` attribute is optional and defaults to `href`.
7897

7998
e.g., to use `NuxtLink` components instead of HTML `a` elements
8099

@@ -89,17 +108,6 @@ pageLinkOptions: {
89108

90109
– the [target attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-target) of links referencing other pages (skipped for pages with `pageLinkeOptions`)
91110

92-
### `imageOptions`: Object
93-
94-
– this Object can be use to specify a custom Vue component you want to use to render pictures. Any other key in this object will spread as element attributes
95-
96-
```js
97-
imageOptions: {
98-
component: "LazyLoadImage",
99-
attribute: "vue-notion-attr"
100-
}
101-
```
102-
103111
### `prism`: Boolean
104112

105113
– whether or not syntax-highlighting using Prims.js should be activated.
@@ -201,7 +209,7 @@ There are a few required steps to allow Nuxt to work with vue-notion
201209
// nuxt.config.js
202210
export default {
203211
// ...
204-
buildModules: ["vue-notion/nuxt"],
212+
buildModules: ["vue-notion/nuxt"]
205213
};
206214
```
207215

src/blocks/helpers/image.vue

+29-15
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,46 @@
11
<template>
22
<div v-if="f.block_aspect_ratio" :style="style">
3-
<component v-if="hasImageComponent" :is="imageOptions.component" class="notion-image-inset" :alt="alt || 'Notion image'" :src="src" v-bind="attrs"/>
4-
<img v-else class="notion-image-inset" :alt="alt || 'Notion image'" :src="src" v-bind="attrs" />
3+
<component
4+
v-if="hasImageComponent"
5+
:is="imageOptions.component"
6+
class="notion-image-inset"
7+
:alt="alt || 'Notion image'"
8+
v-bind="imageProps"
9+
/>
10+
<img
11+
v-else
12+
class="notion-image-inset"
13+
:alt="alt || 'Notion image'"
14+
v-bind="imageProps"
15+
/>
516
</div>
6-
<component v-else-if="hasImageComponent" :is="imageOptions.component" :alt="alt || 'Notion image'" :src="src" v-bind="attrs" />
7-
<img v-else :alt="caption" :src="src" v-bind="attrs" />
17+
<component
18+
v-else-if="hasImageComponent"
19+
:is="imageOptions.component"
20+
:alt="alt || 'Notion image'"
21+
v-bind="imageProps"
22+
/>
23+
<img v-else :alt="alt" v-bind="imageProps" />
824
</template>
925

1026
<script>
11-
import Blockable from "@/lib/blockable";
27+
import Blockable, { blockComputed } from "@/lib/blockable";
1228
1329
export default {
1430
extends: Blockable,
1531
name: "NotionImage",
1632
computed: {
17-
alt() {
18-
return this.caption?.[0][0];
19-
},
20-
src() {
21-
return this.mapImageUrl(this.properties?.source[0][0], this.block);
22-
},
23-
attrs() {
24-
const {component, ...attrs} = this.imageOptions || {}
25-
return attrs;
26-
},
33+
...blockComputed,
2734
hasImageComponent() {
2835
return !!this.imageOptions?.component;
2936
},
37+
imageProps() {
38+
const { component, ...attrs } = this.imageOptions || {};
39+
return {
40+
...attrs,
41+
[this.imageOptions?.src || "src"]: this.src,
42+
};
43+
},
3044
style() {
3145
const aspectRatio =
3246
this.f.block_aspect_ratio || this.f.block_height / this.f.block_width;

src/lib/blockable.js

+17-11
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@ export const blockProps = {
77
embedAllow: { type: String, default: "fullscreen" },
88
fullPage: { type: Boolean, default: false },
99
hideList: { type: Array, default: () => [] },
10+
imageOptions: Object,
11+
katex: { type: Boolean, default: false },
1012
level: { type: Number, default: 0 },
1113
mapImageUrl: Function,
1214
mapPageUrl: Function,
1315
pageLinkOptions: Object,
14-
imageOptions: Object,
1516
pageLinkTarget: { type: String, default: "_self" },
1617
prism: { type: Boolean, default: false },
17-
katex: { type: Boolean, default: false },
1818
textLinkTarget: { type: String, default: "_blank" },
19-
todo: { type: Boolean, default: false },
19+
todo: { type: Boolean, default: false }
2020
};
2121

2222
export const blockComputed = {
@@ -29,16 +29,19 @@ export const blockComputed = {
2929
embedAllow: this.embedAllow,
3030
fullPage: this.fullPage,
3131
hideList: this.hideList,
32+
imageOptions: this.imageOptions,
33+
katex: this.katex,
3234
level: this.level,
3335
mapImageUrl: this.mapImageUrl,
3436
mapPageUrl: this.mapPageUrl,
3537
pageLinkOptions: this.pageLinkOptions,
36-
imageOptions: this.imageOptions,
3738
prism: this.prism,
38-
katex: this.katex,
39-
todo: this.todo,
39+
todo: this.todo
4040
};
4141
},
42+
alt() {
43+
return this.caption?.[0][0];
44+
},
4245
block() {
4346
const id = this.contentId || Object.keys(this.blockMap)[0];
4447
return this.blockMap[id];
@@ -58,7 +61,7 @@ export const blockComputed = {
5861
block_color: this.format?.block_color,
5962
bookmark_icon: this.format?.bookmark_icon,
6063
bookmark_cover: this.format?.bookmark_cover,
61-
display_source: this.format?.display_source,
64+
display_source: this.format?.display_source
6265
};
6366
},
6467
icon() {
@@ -76,6 +79,9 @@ export const blockComputed = {
7679
description() {
7780
return this.properties?.description;
7881
},
82+
src() {
83+
return this.mapImageUrl(this.properties?.source[0][0], this.block);
84+
},
7985
title() {
8086
return this.properties?.title;
8187
},
@@ -90,7 +96,7 @@ export const blockComputed = {
9096
},
9197
parent() {
9298
return this.blockMap[this.value?.parent_id];
93-
},
99+
}
94100
};
95101

96102
export default {
@@ -111,8 +117,8 @@ export default {
111117
},
112118
pageLinkProps(id) {
113119
return {
114-
[this.pageLinkOptions.href]: this.mapPageUrl(id),
120+
[this.pageLinkOptions?.href || "href"]: this.mapPageUrl(id)
115121
};
116-
},
117-
},
122+
}
123+
}
118124
};

0 commit comments

Comments
 (0)