Skip to content

Commit

Permalink
README
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanoverna committed Jan 12, 2021
1 parent 9e8e7ce commit 299bc0a
Show file tree
Hide file tree
Showing 2 changed files with 277 additions and 9 deletions.
277 changes: 271 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ import { Image } from "vue-datocms";

export default {
components: {
"datocms-image": Image
}
"datocms-image": Image,
},
};
```

Expand Down Expand Up @@ -136,16 +136,16 @@ const query = gql`
export default {
components: {
"datocms-image": Image
"datocms-image": Image,
},
data() {
return {
data: null
data: null,
};
},
async mounted() {
this.data = await request({ query });
}
},
};
</script>
```
Expand Down Expand Up @@ -243,7 +243,7 @@ const query = gql`
export default {
data() {
return {
data: null
data: null,
};
},
async mounted() {
Expand All @@ -254,7 +254,272 @@ export default {
return;
}
return toHead(this.data.page.seo, this.data.site.favicon);
},
};
</script>
```

# Structured text

`<datocms-structured-text />` is a Vue component that you can use to render the value contained inside a DatoCMS [Structured Text field type](#).

### Setup

You can register the component globally so it's available in all your apps:

```js
import Vue from "vue";
import { DatocmsStructuredTextPlugin } from "vue-datocms";

Vue.use(DatocmsStructuredTextPlugin);
```

Or use it locally in any of your components:

```js
import { StructuredText } from "vue-datocms";

export default {
components: {
"datocms-structured-text": StructuredText,
},
};
```

## Basic usage

```vue
<template>
<article>
<div v-if="data">
<h1>{{ data.blogPost.title }}</h1>
<datocms-structured-text :structuredText="{data.blogPost.content}" />
{/* ->
<h1>Hello <strong>world!</strong></h1>
*/}
</div>
</article>
</template>
<script>
import { request } from "./lib/datocms";
import { StructuredText } from "vue-datocms";
const query = gql`
query {
blogPost {
title
content {
value
}
}
}
`;
export default {
components: {
"datocms-structured-text": StructuredText,
},
data() {
return {
data: null,
};
},
async mounted() {
this.data = await request({ query });
// data.blogPost.content ->
// {
// value: {
// schema: "dast",
// document: {
// type: "root",
// children: [
// {
// type: "heading",
// level: 1,
// children: [
// {
// type: "span",
// value: "Hello ",
// },
// {
// type: "span",
// marks: ["strong"],
// value: "world!",
// },
// ],
// },
// ],
// },
// },
// }
},
};
</script>
```

## Custom renderers

You can also pass custom renderers for special nodes (inline records, record links and blocks) as an optional parameter like so:

```vue
<template>
<article>
<div v-if="data">
<h1>{{ data.blogPost.title }}</h1>
<datocms-structured-text
:structuredText="{data.blogPost.content}"
:renderInlineRecord="{ renderInlineRecord }"
:renderLinkToRecord="{ renderLinkToRecord }"
:renderBlock="{ renderBlock }"
/>
{/* Final result:
<h1>Welcome onboard <a href="/team/mark-smith">Mark</a></h1>
<p>
So happy to have
<a href="/team/mark-smith">this awesome humang being</a> in our team!
</p>
<img
src="https://www.datocms-assets.com/205/1597757278-austin-distel-wd1lrb9oeeo-unsplash.jpg"
alt="Our team at work"
/>
*/}
</div>
</article>
</template>
<script>
import { request } from "./lib/datocms";
import { StructuredText } from "vue-datocms";
const query = gql`
query {
blogPost {
title
content {
value
}
}
}
`;
export default {
components: {
"datocms-structured-text": StructuredText,
},
data() {
return {
data: null,
};
},
methods: {
renderInlineRecord: ({ record, key, h }) => {
switch (record.__typename) {
case "TeamMemberRecord":
return h(
"a",
{ key, attrs: { href: `/team/${record.slug}` } },
record.firstName,
);
default:
return null;
}
},
renderLinkToRecord: ({ record, children, key, h }) => {
switch (record.__typename) {
case "TeamMemberRecord":
return h(
"a",
{ key, attrs: { href: `/team/${record.slug}` } },
children,
);
default:
return null;
}
},
renderBlock: ({ record, key, h }) => {
switch (record.__typename) {
case "ImageRecord":
return h("img", {
key,
attrs: { src: record.image.url, alt: record.image.alt },
});
default:
return null;
}
},
},
async mounted() {
this.data = await request({ query });
// data.blogPost.content ->
// {
// value: {
// schema: "dast",
// document: {
// type: "root",
// children: [
// {
// type: "heading",
// level: 1,
// children: [
// { type: "span", value: "Welcome onboard " },
// { type: "inlineItem", item: "324321" },
// ],
// },
// {
// type: "paragraph",
// children: [
// { type: "span", value: "So happy to have " },
// {
// type: "itemLink",
// item: "324321",
// children: [
// {
// type: "span",
// marks: ["strong"],
// value: "this awesome humang being",
// },
// ]
// },
// { type: "span", value: " in our team!" },
// ]
// },
// { type: "block", item: "1984559" }
// ],
// },
// },
// links: [
// {
// id: "324321",
// __typename: "TeamMemberRecord",
// firstName: "Mark",
// slug: "mark-smith",
// },
// ],
// blocks: [
// {
// id: "324321",
// __typename: "ImageRecord",
// image: {
// alt: "Our team at work",
// url: "https://www.datocms-assets.com/205/1597757278-austin-distel-wd1lrb9oeeo-unsplash.jpg",
// },
// },
// ],
// }
},
};
</script>
```

## Props

| prop | type | required | description | default |
| ------------------ | -------------------------------------------------------- | ----------------------------------------------------- | --------------------------------------------------------------------------- | ---------------- |
| structuredText | structured text field value | :white_check_mark: | The actual field value you get from DatoCMS | |
| renderInlineRecord | `({ record }) => VNode \| null` | Only required if document contains `inlineItem` nodes | Convert an `inlineItem` DAST node into React | `[]` |
| renderLinkToRecord | `({ record, children }) => VNode \| null` | Only required if document contains `itemLink` nodes | Convert an `itemLink` DAST node into React | `null` |
| renderBlock | `({ record }) => VNode \| null` | Only required if document contains `block` nodes | Convert a `block` DAST node into React | `null` |
| customRules | `Array<RenderRule>` | :x: | Customize how document is converted in JSX (use `renderRule()` to generate) | `null` |
| renderText | `(text: string, key: string) => VNode \| string \| null` | :x: | Convert a simple string text into React | `(text) => text` |
9 changes: 6 additions & 3 deletions src/StructuredText/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const StructuredText = {
"renderLinkToRecord",
"renderBlock",
"customRules",
"renderText",
],

render(h, ctx) {
Expand All @@ -28,6 +29,7 @@ export const StructuredText = {
renderInlineRecord,
renderLinkToRecord,
renderBlock,
renderText,
customRules,
} = ctx.props;

Expand All @@ -48,7 +50,7 @@ export const StructuredText = {
renderNode: hAdapter,
renderMark: hAdapter,
renderFragment: (children, key) => h("div", { key }, children),
renderText: (text) => text,
renderText: renderText || ((text) => text),
};

const result = render(
Expand Down Expand Up @@ -81,7 +83,7 @@ export const StructuredText = {
);
}

return renderInlineRecord({ record: item, key, h });
return renderInlineRecord({ record: item, key, h, adapter });
}),
renderRule(isItemLink, ({ node, key, children }) => {
if (!renderLinkToRecord) {
Expand Down Expand Up @@ -114,6 +116,7 @@ export const StructuredText = {
children: children,
key,
h,
adapter,
});
}),
renderRule(isBlock, ({ node, key }) => {
Expand Down Expand Up @@ -142,7 +145,7 @@ export const StructuredText = {
);
}

return renderBlock({ record: item, key, h });
return renderBlock({ record: item, key, h, adapter });
}),
].concat(customRules || []),
);
Expand Down

0 comments on commit 299bc0a

Please sign in to comment.