@datocms/astro 0.2.2 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/StructuredText/Node.astro +84 -42
- package/src/StructuredText/README.md +55 -41
- package/src/StructuredText/StructuredText.astro +25 -8
- package/src/StructuredText/index.ts +4 -1
- package/src/StructuredText/nodes/Block.astro +27 -0
- package/src/StructuredText/nodes/InlineItem.astro +27 -0
- package/src/StructuredText/nodes/ItemLink.astro +34 -0
- package/src/StructuredText/types.ts +17 -2
- package/src/StructuredText/utils.ts +0 -90
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@datocms/astro",
|
|
3
3
|
"description": "A set of components and utilities to work faster with DatoCMS in Astro projects.",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.3.1",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@0no-co/graphql.web": "^1.0.7",
|
|
47
47
|
"datocms-listen": "^1.0.1",
|
|
48
|
+
"datocms-structured-text-generic-html-renderer": "^4.0.1",
|
|
48
49
|
"datocms-structured-text-utils": "^4.0.1"
|
|
49
50
|
},
|
|
50
51
|
"peerDependencies": {
|
|
@@ -1,70 +1,112 @@
|
|
|
1
1
|
---
|
|
2
2
|
import {
|
|
3
3
|
type Block,
|
|
4
|
+
type Record as DatocmsRecord,
|
|
4
5
|
type InlineItem,
|
|
5
6
|
type ItemLink,
|
|
6
|
-
type Node,
|
|
7
|
-
type StructuredText,
|
|
7
|
+
type Node as DastNode,
|
|
8
8
|
hasChildren,
|
|
9
9
|
isBlock,
|
|
10
10
|
isInlineItem,
|
|
11
11
|
isItemLink,
|
|
12
|
+
RenderError,
|
|
12
13
|
} from 'datocms-structured-text-utils';
|
|
13
14
|
|
|
14
|
-
import
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
import Blockquote from './nodes/Blockquote.astro';
|
|
16
|
+
import Code from './nodes/Code.astro';
|
|
17
|
+
import Heading from './nodes/Heading.astro';
|
|
18
|
+
import Link from './nodes/Link.astro';
|
|
19
|
+
import List from './nodes/List.astro';
|
|
20
|
+
import ListItem from './nodes/ListItem.astro';
|
|
21
|
+
import Paragraph from './nodes/Paragraph.astro';
|
|
22
|
+
import Root from './nodes/Root.astro';
|
|
23
|
+
import Span from './nodes/Span.astro';
|
|
24
|
+
import ThematicBreak from './nodes/ThematicBreak.astro';
|
|
25
|
+
import BlockComponent from './nodes/Block.astro';
|
|
26
|
+
import InlineItemComponent from './nodes/InlineItem.astro';
|
|
27
|
+
import ItemLinkComponent from './nodes/ItemLink.astro';
|
|
20
28
|
|
|
21
|
-
import type {
|
|
29
|
+
import type { BlockComponents, InlineItemComponents, ItemLinkComponents, Overrides } from './types';
|
|
22
30
|
|
|
23
31
|
interface Props {
|
|
24
|
-
node:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
32
|
+
node: DastNode;
|
|
33
|
+
|
|
34
|
+
blocks?: DatocmsRecord[];
|
|
35
|
+
links?: DatocmsRecord[];
|
|
36
|
+
|
|
37
|
+
blockComponents?: BlockComponents<DatocmsRecord, DatocmsRecord>;
|
|
38
|
+
itemLinkComponents?: ItemLinkComponents<DatocmsRecord, DatocmsRecord>;
|
|
39
|
+
inlineItemComponents?: InlineItemComponents<DatocmsRecord, DatocmsRecord>;
|
|
40
|
+
overrides?: Overrides;
|
|
28
41
|
}
|
|
29
42
|
|
|
30
|
-
const { node,
|
|
43
|
+
const { node, ...rest } = Astro.props;
|
|
44
|
+
|
|
45
|
+
const { blocks, links, blockComponents, itemLinkComponents, inlineItemComponents, overrides } =
|
|
46
|
+
rest;
|
|
47
|
+
|
|
48
|
+
function findRecordInBlocks(node: Block) {
|
|
49
|
+
const record = (blocks || []).find(({ id }) => id === node.item);
|
|
31
50
|
|
|
32
|
-
|
|
33
|
-
|
|
51
|
+
if (!record) {
|
|
52
|
+
throw new RenderError(
|
|
53
|
+
`The Structured Text document contains a 'block' node, but cannot find a record with ID ${node.item} inside data.blocks!`,
|
|
54
|
+
node,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
34
57
|
|
|
35
|
-
|
|
36
|
-
|
|
58
|
+
return record;
|
|
59
|
+
}
|
|
37
60
|
|
|
38
|
-
|
|
61
|
+
function findRecordInLinks(node: ItemLink | InlineItem) {
|
|
62
|
+
const record = (links || []).find(({ id }) => id === node.item);
|
|
39
63
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
64
|
+
if (!record) {
|
|
65
|
+
throw new RenderError(
|
|
66
|
+
`The Structured Text document contains an '${node.type}' node, but cannot find a record with ID ${node.item} inside data.links!`,
|
|
67
|
+
node,
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return record;
|
|
72
|
+
}
|
|
43
73
|
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
74
|
+
const defaultComponents: Overrides = {
|
|
75
|
+
paragraph: Paragraph,
|
|
76
|
+
root: Root,
|
|
77
|
+
span: Span,
|
|
78
|
+
link: Link,
|
|
79
|
+
list: List,
|
|
80
|
+
heading: Heading,
|
|
81
|
+
blockquote: Blockquote,
|
|
82
|
+
listItem: ListItem,
|
|
83
|
+
thematicBreak: ThematicBreak,
|
|
84
|
+
code: Code,
|
|
85
|
+
itemLink: ItemLinkComponent,
|
|
86
|
+
inlineItem: InlineItemComponent,
|
|
87
|
+
block: BlockComponent,
|
|
88
|
+
};
|
|
47
89
|
|
|
48
|
-
const
|
|
90
|
+
const otherNodeComponents: Overrides = { ...defaultComponents, ...overrides };
|
|
91
|
+
const Component = otherNodeComponents[node.type];
|
|
49
92
|
---
|
|
50
93
|
|
|
51
94
|
<>
|
|
52
95
|
{
|
|
53
|
-
|
|
54
|
-
(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
{
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
))
|
|
96
|
+
isBlock(node) ? (
|
|
97
|
+
<Component {node} block={findRecordInBlocks(node)} {blockComponents} />
|
|
98
|
+
) : isInlineItem(node) ? (
|
|
99
|
+
<Component {node} record={findRecordInLinks(node)} {inlineItemComponents} />
|
|
100
|
+
) : isItemLink(node) ? (
|
|
101
|
+
<Component {node} record={findRecordInLinks(node)} {itemLinkComponents}>
|
|
102
|
+
{node.children.map((child) => (
|
|
103
|
+
<Astro.self node={child} {...rest} />
|
|
104
|
+
))}
|
|
105
|
+
</Component>
|
|
106
|
+
) : (
|
|
107
|
+
<Component {node}>
|
|
108
|
+
{hasChildren(node) && node.children.map((child) => <Astro.self node={child} {...rest} />)}
|
|
109
|
+
</Component>
|
|
110
|
+
)
|
|
69
111
|
}
|
|
70
112
|
</>
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
- [Setup](#setup)
|
|
11
11
|
- [Basic usage](#basic-usage)
|
|
12
12
|
- [Customization](#customization)
|
|
13
|
-
- [Custom components for blocks](#custom-components-for-blocks)
|
|
13
|
+
- [Custom components for blocks, inline records or links to records](#custom-components-for-blocks-inline-records-or-links-to-records)
|
|
14
14
|
- [Override default rendering of nodes](#override-default-rendering-of-nodes)
|
|
15
15
|
- [Props](#props)
|
|
16
16
|
|
|
@@ -57,21 +57,25 @@ The `<StructuredText />` component comes with a set of default components that a
|
|
|
57
57
|
|
|
58
58
|
You need to use custom components in the following cases:
|
|
59
59
|
|
|
60
|
-
- you have to render blocks, inline
|
|
60
|
+
- you have to render blocks, inline records or links to records: there's no conventional way of rendering theses nodes, so you must create and pass custom components;
|
|
61
61
|
- you need to render a conventional node differently (e.g. you may want a custom render for blockquotes)
|
|
62
62
|
|
|
63
|
-
### Custom components for blocks
|
|
63
|
+
### Custom components for blocks, inline records or links to records
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
- Astro components passed in `blockComponents` will be used to render blocks and will receive a `block` prop containing the actual block data.
|
|
66
|
+
- Astro components passed in `inlineItemComponents` will be used to render inline records and will receive a `record` prop containing the actual record.
|
|
67
|
+
- Astro components passed in `itemLinkComponents` will be used to render links to records and will receive the following props: `node` (the actual `'inlineItem'` node), `record` (the record linked to the node), and `attrs` (the custom attributes for the link specified by the node).
|
|
66
68
|
|
|
67
69
|
```astro
|
|
68
70
|
---
|
|
69
|
-
import { isBlock, isInlineItem, isItemLink } from 'datocms-structured-text-utils';
|
|
70
71
|
import { StructuredText } from '@datocms/astro/StructuredText';
|
|
72
|
+
import { executeQuery } from '@datocms/cda-client';
|
|
73
|
+
|
|
74
|
+
import Cta from '~/components/Cta/index.astro';
|
|
75
|
+
import NewsletterSignup from '~/components/NewsletterSignup/index.astro';
|
|
71
76
|
|
|
72
|
-
import
|
|
73
|
-
import
|
|
74
|
-
import ItemLink from '~/components/ItemLink/index.astro';
|
|
77
|
+
import InlineTeamMember from '~/components/InlineTeamMember/index.astro';
|
|
78
|
+
import LinkToTeamMember from '~/components/LinkToTeamMember/index.astro';
|
|
75
79
|
|
|
76
80
|
const query = gql`
|
|
77
81
|
query {
|
|
@@ -79,32 +83,27 @@ const query = gql`
|
|
|
79
83
|
title
|
|
80
84
|
content {
|
|
81
85
|
value
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
... on TeamMemberRecord {
|
|
86
|
+
blocks {
|
|
87
|
+
... on RecordInterface {
|
|
85
88
|
id
|
|
86
|
-
|
|
87
|
-
|
|
89
|
+
__typename
|
|
90
|
+
}
|
|
91
|
+
... on CtaRecord {
|
|
92
|
+
label
|
|
93
|
+
url
|
|
94
|
+
}
|
|
95
|
+
... on NewsletterSignupRecord {
|
|
96
|
+
title
|
|
88
97
|
}
|
|
89
98
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
... on ImageRecord {
|
|
99
|
+
links {
|
|
100
|
+
... on RecordInterface {
|
|
93
101
|
id
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
src
|
|
100
|
-
width
|
|
101
|
-
height
|
|
102
|
-
aspectRatio
|
|
103
|
-
alt
|
|
104
|
-
title
|
|
105
|
-
base64
|
|
106
|
-
}
|
|
107
|
-
}
|
|
102
|
+
__typename
|
|
103
|
+
}
|
|
104
|
+
... on TeamMemberRecord {
|
|
105
|
+
firstName
|
|
106
|
+
slug
|
|
108
107
|
}
|
|
109
108
|
}
|
|
110
109
|
}
|
|
@@ -119,11 +118,16 @@ const { blogPost } = await executeQuery(query, { token: '<YOUR-API-TOKEN>' });
|
|
|
119
118
|
<h1>{blogPost.title}</h1>
|
|
120
119
|
<StructuredText
|
|
121
120
|
data={blogPost.content}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
121
|
+
blockComponents={{
|
|
122
|
+
CtaRecord: Cta,
|
|
123
|
+
NewsletterSignupRecord: NewsletterSignup,
|
|
124
|
+
}}
|
|
125
|
+
inlineItemComponents={{
|
|
126
|
+
TeamMemberRecord: InlineTeamMember,
|
|
127
|
+
}}
|
|
128
|
+
itemLinkComponents={{
|
|
129
|
+
TeamMemberRecord: LinkToTeamMember,
|
|
130
|
+
}}
|
|
127
131
|
/>
|
|
128
132
|
</article>
|
|
129
133
|
```
|
|
@@ -135,20 +139,30 @@ const { blogPost } = await executeQuery(query, { token: '<YOUR-API-TOKEN>' });
|
|
|
135
139
|
- For `heading` nodes, you might want to add an anchor;
|
|
136
140
|
- For `code` nodes, you might want to use a custom syntax highlighting component;
|
|
137
141
|
|
|
138
|
-
In this case, you can easily override default rendering rules with the `
|
|
142
|
+
In this case, you can easily override default rendering rules with the `overrides` prop.
|
|
139
143
|
|
|
140
144
|
```astro
|
|
141
145
|
---
|
|
142
146
|
import { isHeading } from 'datocms-structured-text-utils';
|
|
143
147
|
import HeadingWithAnchorLink from '~/components/HeadingWithAnchorLink/index.astro';
|
|
148
|
+
import Code from '~/components/Code/index.astro';
|
|
144
149
|
---
|
|
145
150
|
|
|
146
|
-
<StructuredText
|
|
151
|
+
<StructuredText
|
|
152
|
+
data={blogPost.content}
|
|
153
|
+
components={{
|
|
154
|
+
heading: HeadingWithAnchorLink,
|
|
155
|
+
code: Code,
|
|
156
|
+
}}
|
|
157
|
+
/>
|
|
147
158
|
```
|
|
148
159
|
|
|
149
160
|
## Props
|
|
150
161
|
|
|
151
|
-
| prop
|
|
152
|
-
|
|
|
153
|
-
| data
|
|
154
|
-
|
|
|
162
|
+
| prop | type | required | description |
|
|
163
|
+
| -------------------- | -------------------------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------- |
|
|
164
|
+
| data | `StructuredText \| DastNode` | :white_check_mark: | The actual [field value](https://www.datocms.com/docs/structured-text/dast) you get from DatoCMS |
|
|
165
|
+
| blockComponents | `Record<string, AstroComponent>` | | An object in which the keys are the `__typename` of the blocks to be rendered, and the values are the Astro components |
|
|
166
|
+
| itemLinkComponents | `Record<string, AstroComponent>` | | An object in which the keys are the `__typename` of the records to be rendered, and the values are the Astro components |
|
|
167
|
+
| inlineItemComponents | `Record<string, AstroComponent>` | | An object in which the keys are the `__typename` of the records to be rendered, and the values are the Astro components |
|
|
168
|
+
| overrides | `Record<string, AstroComponent>` | | An object in which the keys are the types of DAST nodes to override, and the values are the Astro components |
|
|
@@ -1,25 +1,42 @@
|
|
|
1
1
|
---
|
|
2
2
|
import {
|
|
3
|
-
type
|
|
3
|
+
type Node as DastNode,
|
|
4
4
|
type Document,
|
|
5
|
+
type Record as DatocmsRecord,
|
|
6
|
+
type StructuredText,
|
|
7
|
+
isDocument,
|
|
8
|
+
isNode,
|
|
5
9
|
isStructuredText,
|
|
6
10
|
} from 'datocms-structured-text-utils';
|
|
7
11
|
|
|
8
12
|
import Node from './Node.astro';
|
|
9
|
-
import type {
|
|
13
|
+
import type { BlockComponents, InlineItemComponents, ItemLinkComponents, Overrides } from './types';
|
|
14
|
+
|
|
15
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
16
|
+
interface Props<R1 extends DatocmsRecord = any, R2 extends DatocmsRecord = any> {
|
|
17
|
+
data: StructuredText<R1, R2> | Document | DastNode | null | undefined;
|
|
10
18
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
19
|
+
blockComponents?: BlockComponents<R1, R2>;
|
|
20
|
+
itemLinkComponents?: ItemLinkComponents<R1, R2>;
|
|
21
|
+
inlineItemComponents?: InlineItemComponents<R1, R2>;
|
|
22
|
+
overrides?: Overrides;
|
|
14
23
|
}
|
|
15
24
|
|
|
16
|
-
const { data,
|
|
25
|
+
const { data, ...rest } = Astro.props;
|
|
17
26
|
|
|
18
|
-
const node = data
|
|
27
|
+
const node = !data
|
|
28
|
+
? null
|
|
29
|
+
: isStructuredText(data) && isDocument(data.value)
|
|
30
|
+
? data.value.document
|
|
31
|
+
: isDocument(data)
|
|
32
|
+
? data.document
|
|
33
|
+
: isNode(data)
|
|
34
|
+
? data
|
|
35
|
+
: undefined;
|
|
19
36
|
|
|
20
37
|
const blocks = isStructuredText(data) ? data?.blocks : undefined;
|
|
21
38
|
|
|
22
39
|
const links = isStructuredText(data) ? data?.links : undefined;
|
|
23
40
|
---
|
|
24
41
|
|
|
25
|
-
{node && <Node {node} {blocks} {links} {
|
|
42
|
+
{node && <Node {node} {blocks} {links} {...rest} />}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
import {
|
|
3
|
+
type Record as DatocmsRecord,
|
|
4
|
+
RenderError,
|
|
5
|
+
type Block,
|
|
6
|
+
} from 'datocms-structured-text-utils';
|
|
7
|
+
import type { BlockComponents } from '../types';
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
node: Block;
|
|
11
|
+
block: DatocmsRecord;
|
|
12
|
+
blockComponents?: BlockComponents<DatocmsRecord, DatocmsRecord>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const { node, block, blockComponents } = Astro.props;
|
|
16
|
+
|
|
17
|
+
const Component = blockComponents?.[block.__typename];
|
|
18
|
+
|
|
19
|
+
if (!Component) {
|
|
20
|
+
throw new RenderError(
|
|
21
|
+
`The Structured Text document contains a 'block' node, but no component for rendering it is specified in blockComponents prop!`,
|
|
22
|
+
node,
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
<Component block={block} />
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
import {
|
|
3
|
+
type Record as DatocmsRecord,
|
|
4
|
+
RenderError,
|
|
5
|
+
type InlineItem,
|
|
6
|
+
} from 'datocms-structured-text-utils';
|
|
7
|
+
import type { InlineItemComponents } from '../types';
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
node: InlineItem;
|
|
11
|
+
record: DatocmsRecord;
|
|
12
|
+
inlineItemComponents?: InlineItemComponents<DatocmsRecord, DatocmsRecord>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const { node, record, inlineItemComponents } = Astro.props;
|
|
16
|
+
|
|
17
|
+
const Component = inlineItemComponents?.[record.__typename];
|
|
18
|
+
|
|
19
|
+
if (!Component) {
|
|
20
|
+
throw new RenderError(
|
|
21
|
+
`The Structured Text document contains an 'inlineItem' node, but no component for rendering it is specified in the inlineItemComponents prop!`,
|
|
22
|
+
node,
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
<Component {record} />
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
import {
|
|
3
|
+
type Record as DatocmsRecord,
|
|
4
|
+
RenderError,
|
|
5
|
+
type ItemLink,
|
|
6
|
+
} from 'datocms-structured-text-utils';
|
|
7
|
+
|
|
8
|
+
import type { ItemLinkComponents } from '../types';
|
|
9
|
+
|
|
10
|
+
import { defaultMetaTransformer } from 'datocms-structured-text-generic-html-renderer';
|
|
11
|
+
|
|
12
|
+
interface Props {
|
|
13
|
+
node: ItemLink;
|
|
14
|
+
record: DatocmsRecord;
|
|
15
|
+
itemLinkComponents?: ItemLinkComponents<DatocmsRecord, DatocmsRecord>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const { node, record, itemLinkComponents } = Astro.props;
|
|
19
|
+
|
|
20
|
+
const Component = itemLinkComponents?.[record.__typename];
|
|
21
|
+
|
|
22
|
+
if (!Component) {
|
|
23
|
+
throw new RenderError(
|
|
24
|
+
`The Structured Text document contains an 'itemLink' node, but no component for rendering it is specified in the itemLinkComponents prop!`,
|
|
25
|
+
node,
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const { meta } = node;
|
|
30
|
+
|
|
31
|
+
const attrs = meta ? defaultMetaTransformer({ node, meta }) : {};
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
<Component {node} {record} {attrs}><slot /></Component>
|
|
@@ -1,6 +1,21 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Record as DatocmsRecord, NodeType } from 'datocms-structured-text-utils';
|
|
2
2
|
|
|
3
3
|
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
4
4
|
type AstroComponent = (props: any) => any;
|
|
5
5
|
|
|
6
|
-
export type
|
|
6
|
+
export type BlockComponents<R1 extends DatocmsRecord, R2 extends DatocmsRecord> = Record<
|
|
7
|
+
R1['__typename'],
|
|
8
|
+
AstroComponent
|
|
9
|
+
>;
|
|
10
|
+
|
|
11
|
+
export type ItemLinkComponents<R1 extends DatocmsRecord, R2 extends DatocmsRecord> = Record<
|
|
12
|
+
R2['__typename'],
|
|
13
|
+
AstroComponent
|
|
14
|
+
>;
|
|
15
|
+
|
|
16
|
+
export type InlineItemComponents<R1 extends DatocmsRecord, R2 extends DatocmsRecord> = Record<
|
|
17
|
+
R2['__typename'],
|
|
18
|
+
AstroComponent
|
|
19
|
+
>;
|
|
20
|
+
|
|
21
|
+
export type Overrides = Record<NodeType, AstroComponent>;
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type Block,
|
|
3
|
-
type InlineItem,
|
|
4
|
-
type ItemLink,
|
|
5
|
-
type Node,
|
|
6
|
-
RenderError,
|
|
7
|
-
type StructuredText,
|
|
8
|
-
isBlock,
|
|
9
|
-
isBlockquote,
|
|
10
|
-
isCode,
|
|
11
|
-
isHeading,
|
|
12
|
-
isInlineItem,
|
|
13
|
-
isItemLink,
|
|
14
|
-
isLink,
|
|
15
|
-
isList,
|
|
16
|
-
isListItem,
|
|
17
|
-
isParagraph,
|
|
18
|
-
isRoot,
|
|
19
|
-
isSpan,
|
|
20
|
-
isThematicBreak,
|
|
21
|
-
} from 'datocms-structured-text-utils';
|
|
22
|
-
|
|
23
|
-
import Blockquote from './nodes/Blockquote.astro';
|
|
24
|
-
import Code from './nodes/Code.astro';
|
|
25
|
-
import Heading from './nodes/Heading.astro';
|
|
26
|
-
import Link from './nodes/Link.astro';
|
|
27
|
-
import List from './nodes/List.astro';
|
|
28
|
-
import ListItem from './nodes/ListItem.astro';
|
|
29
|
-
import Paragraph from './nodes/Paragraph.astro';
|
|
30
|
-
import Root from './nodes/Root.astro';
|
|
31
|
-
import Span from './nodes/Span.astro';
|
|
32
|
-
import ThematicBreak from './nodes/ThematicBreak.astro';
|
|
33
|
-
|
|
34
|
-
import type { PredicateComponentTuple } from './types';
|
|
35
|
-
|
|
36
|
-
export const defaultComponents: PredicateComponentTuple[] = [
|
|
37
|
-
[isParagraph, Paragraph],
|
|
38
|
-
[isRoot, Root],
|
|
39
|
-
[isSpan, Span],
|
|
40
|
-
[isLink, Link],
|
|
41
|
-
[isList, List],
|
|
42
|
-
[isHeading, Heading],
|
|
43
|
-
[isBlockquote, Blockquote],
|
|
44
|
-
[isListItem, ListItem],
|
|
45
|
-
[isThematicBreak, ThematicBreak],
|
|
46
|
-
[isCode, Code],
|
|
47
|
-
];
|
|
48
|
-
|
|
49
|
-
export const throwRenderErrorForMissingComponent = (node: Node) => {
|
|
50
|
-
if (isInlineItem(node)) {
|
|
51
|
-
throw new RenderError(
|
|
52
|
-
`The Structured Text document contains an 'inlineItem' node, but no component for rendering is specified!`,
|
|
53
|
-
node,
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (isItemLink(node)) {
|
|
58
|
-
throw new RenderError(
|
|
59
|
-
`The Structured Text document contains an 'itemLink' node, but no component for rendering is specified!`,
|
|
60
|
-
node,
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (isBlock(node)) {
|
|
65
|
-
throw new RenderError(
|
|
66
|
-
`The Structured Text document contains a 'block' node, but no component for rendering is specified!`,
|
|
67
|
-
node,
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
export const throwRenderErrorForMissingBlock = (node: Block) => {
|
|
73
|
-
throw new RenderError(
|
|
74
|
-
`The Structured Text document contains a 'block' node, but cannot find a record with ID ${node.item} inside data.blocks!`,
|
|
75
|
-
node,
|
|
76
|
-
);
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
export const throwRenderErrorForMissingLink = (node: ItemLink | InlineItem) => {
|
|
80
|
-
throw new RenderError(
|
|
81
|
-
`The Structured Text document contains an 'itemLink' node, but cannot find a record with ID ${node.item} inside data.links!`,
|
|
82
|
-
node,
|
|
83
|
-
);
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
export const findBlock = (node: Block, blocks: StructuredText['blocks']) =>
|
|
87
|
-
(blocks || []).find(({ id }) => id === node.item);
|
|
88
|
-
|
|
89
|
-
export const findLink = (node: ItemLink | InlineItem, links: StructuredText['links']) =>
|
|
90
|
-
(links || []).find(({ id }) => id === node.item);
|