@datocms/astro 0.3.2 → 0.3.4

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 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.3.2",
5
+ "version": "0.3.4",
6
6
  "sideEffects": false,
7
7
  "repository": {
8
8
  "type": "git",
@@ -10,6 +10,8 @@ import {
10
10
  isInlineItem,
11
11
  isItemLink,
12
12
  RenderError,
13
+ type NodeType,
14
+ isSpan,
13
15
  } from 'datocms-structured-text-utils';
14
16
 
15
17
  import Blockquote from './nodes/Blockquote.astro';
@@ -26,7 +28,14 @@ import BlockComponent from './nodes/Block.astro';
26
28
  import InlineItemComponent from './nodes/InlineItem.astro';
27
29
  import ItemLinkComponent from './nodes/ItemLink.astro';
28
30
 
29
- import type { BlockComponents, InlineItemComponents, ItemLinkComponents, Overrides } from './types';
31
+ import type {
32
+ BlockComponents,
33
+ InlineRecordComponents,
34
+ LinkToRecordComponents,
35
+ NodeOverrides,
36
+ AstroComponent,
37
+ MarkOverrides,
38
+ } from './types';
30
39
 
31
40
  interface Props {
32
41
  node: DastNode;
@@ -35,15 +44,24 @@ interface Props {
35
44
  links?: DatocmsRecord[];
36
45
 
37
46
  blockComponents?: BlockComponents<DatocmsRecord, DatocmsRecord>;
38
- itemLinkComponents?: ItemLinkComponents<DatocmsRecord, DatocmsRecord>;
39
- inlineItemComponents?: InlineItemComponents<DatocmsRecord, DatocmsRecord>;
40
- overrides?: Overrides;
47
+ linkToRecordComponents?: LinkToRecordComponents<DatocmsRecord, DatocmsRecord>;
48
+ inlineRecordComponents?: InlineRecordComponents<DatocmsRecord, DatocmsRecord>;
49
+
50
+ nodeOverrides?: NodeOverrides;
51
+ markOverrides?: MarkOverrides;
41
52
  }
42
53
 
43
54
  const { node, ...rest } = Astro.props;
44
55
 
45
- const { blocks, links, blockComponents, itemLinkComponents, inlineItemComponents, overrides } =
46
- rest;
56
+ const {
57
+ blocks,
58
+ links,
59
+ blockComponents,
60
+ linkToRecordComponents,
61
+ inlineRecordComponents,
62
+ nodeOverrides,
63
+ markOverrides,
64
+ } = rest;
47
65
 
48
66
  function findRecordInBlocks(node: Block) {
49
67
  const record = (blocks || []).find(({ id }) => id === node.item);
@@ -71,7 +89,7 @@ function findRecordInLinks(node: ItemLink | InlineItem) {
71
89
  return record;
72
90
  }
73
91
 
74
- const defaultComponents: Overrides = {
92
+ const defaultComponents: Record<NodeType, AstroComponent> = {
75
93
  paragraph: Paragraph,
76
94
  root: Root,
77
95
  span: Span,
@@ -87,7 +105,11 @@ const defaultComponents: Overrides = {
87
105
  block: BlockComponent,
88
106
  };
89
107
 
90
- const otherNodeComponents: Overrides = { ...defaultComponents, ...overrides };
108
+ const otherNodeComponents: Record<NodeType, AstroComponent> = {
109
+ ...defaultComponents,
110
+ ...nodeOverrides,
111
+ };
112
+
91
113
  const Component = otherNodeComponents[node.type];
92
114
  ---
93
115
 
@@ -96,13 +118,15 @@ const Component = otherNodeComponents[node.type];
96
118
  isBlock(node) ? (
97
119
  <Component {node} block={findRecordInBlocks(node)} {blockComponents} />
98
120
  ) : isInlineItem(node) ? (
99
- <Component {node} record={findRecordInLinks(node)} {inlineItemComponents} />
121
+ <Component {node} record={findRecordInLinks(node)} {inlineRecordComponents} />
100
122
  ) : isItemLink(node) ? (
101
- <Component {node} record={findRecordInLinks(node)} {itemLinkComponents}>
123
+ <Component {node} record={findRecordInLinks(node)} {linkToRecordComponents}>
102
124
  {node.children.map((child) => (
103
125
  <Astro.self node={child} {...rest} />
104
126
  ))}
105
127
  </Component>
128
+ ) : isSpan(node) ? (
129
+ <Component {node} {markOverrides} />
106
130
  ) : (
107
131
  <Component {node}>
108
132
  {hasChildren(node) && node.children.map((child) => <Astro.self node={child} {...rest} />)}
@@ -63,8 +63,8 @@ You need to use custom components in the following cases:
63
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
+ - Astro components passed in `inlineRecordComponents` will be used to render inline records and will receive a `record` prop containing the actual record.
67
+ - Astro components passed in `linkToRecordComponents` 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).
68
68
 
69
69
  ```astro
70
70
  ---
@@ -122,10 +122,10 @@ const { blogPost } = await executeQuery(query, { token: '<YOUR-API-TOKEN>' });
122
122
  CtaRecord: Cta,
123
123
  NewsletterSignupRecord: NewsletterSignup,
124
124
  }}
125
- inlineItemComponents={{
125
+ inlineRecordComponents={{
126
126
  TeamMemberRecord: InlineTeamMember,
127
127
  }}
128
- itemLinkComponents={{
128
+ linkToRecordComponents={{
129
129
  TeamMemberRecord: LinkToTeamMember,
130
130
  }}
131
131
  />
@@ -139,7 +139,7 @@ const { blogPost } = await executeQuery(query, { token: '<YOUR-API-TOKEN>' });
139
139
  - For `heading` nodes, you might want to add an anchor;
140
140
  - For `code` nodes, you might want to use a custom syntax highlighting component;
141
141
 
142
- In this case, you can easily override default rendering rules with the `overrides` prop.
142
+ In this case, you can easily override default rendering rules with the `nodeOverrides` prop.
143
143
 
144
144
  ```astro
145
145
  ---
@@ -150,7 +150,7 @@ import Code from '~/components/Code/index.astro';
150
150
 
151
151
  <StructuredText
152
152
  data={blogPost.content}
153
- components={{
153
+ nodeOverrides={{
154
154
  heading: HeadingWithAnchorLink,
155
155
  code: Code,
156
156
  }}
@@ -159,10 +159,11 @@ import Code from '~/components/Code/index.astro';
159
159
 
160
160
  ## Props
161
161
 
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 |
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
+ | linkToRecordComponents | `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
+ | inlineRecordComponents | `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
+ | nodeOverrides | `Record<string, AstroComponent>` | | An object in which the keys are the types of DAST nodes to override, and the values are the Astro components |
169
+ | markOverrides | `Record<string, AstroComponent>` | | An object in which the keys are the types of `span` node marks to override, and the values are the Astro components |
@@ -10,7 +10,13 @@ import {
10
10
  } from 'datocms-structured-text-utils';
11
11
 
12
12
  import Node from './Node.astro';
13
- import type { BlockComponents, InlineItemComponents, ItemLinkComponents, Overrides } from './types';
13
+ import type {
14
+ BlockComponents,
15
+ InlineRecordComponents,
16
+ LinkToRecordComponents,
17
+ NodeOverrides,
18
+ MarkOverrides,
19
+ } from './types';
14
20
 
15
21
  // It would be better to type this as:
16
22
  //
@@ -19,12 +25,20 @@ import type { BlockComponents, InlineItemComponents, ItemLinkComponents, Overrid
19
25
  // but it's currently not possible: https://github.com/withastro/roadmap/discussions/601#discussioncomment-10333959
20
26
 
21
27
  interface Props {
28
+ /** The actual [field value](https://www.datocms.com/docs/structured-text/dast) you get from a DatoCMS Structured Text field */
22
29
  data: StructuredText<DatocmsRecord, DatocmsRecord> | Document | DastNode | null | undefined;
23
30
 
31
+ /** An object in which the keys are the `__typename` of the blocks to be rendered, and the values are the Astro components */
24
32
  blockComponents?: BlockComponents<DatocmsRecord, DatocmsRecord>;
25
- itemLinkComponents?: ItemLinkComponents<DatocmsRecord, DatocmsRecord>;
26
- inlineItemComponents?: InlineItemComponents<DatocmsRecord, DatocmsRecord>;
27
- overrides?: Overrides;
33
+ /** An object in which the keys are the `__typename` of the records to be rendered, and the values are the Astro components */
34
+ linkToRecordComponents?: LinkToRecordComponents<DatocmsRecord, DatocmsRecord>;
35
+ /** An object in which the keys are the `__typename` of the records to be rendered, and the values are the Astro components */
36
+ inlineRecordComponents?: InlineRecordComponents<DatocmsRecord, DatocmsRecord>;
37
+
38
+ /** An object in which the keys are the types of DAST nodes to override, and the values are the Astro components */
39
+ nodeOverrides?: NodeOverrides;
40
+ /** An object in which the keys are the types of `span` node marks to override, and the values are the Astro components */
41
+ markOverrides?: MarkOverrides;
28
42
  }
29
43
 
30
44
  const { data, ...rest } = Astro.props;
@@ -4,21 +4,21 @@ import {
4
4
  RenderError,
5
5
  type InlineItem,
6
6
  } from 'datocms-structured-text-utils';
7
- import type { InlineItemComponents } from '../types';
7
+ import type { InlineRecordComponents } from '../types';
8
8
 
9
9
  interface Props {
10
10
  node: InlineItem;
11
11
  record: DatocmsRecord;
12
- inlineItemComponents?: InlineItemComponents<DatocmsRecord, DatocmsRecord>;
12
+ inlineRecordComponents?: InlineRecordComponents<DatocmsRecord, DatocmsRecord>;
13
13
  }
14
14
 
15
- const { node, record, inlineItemComponents } = Astro.props;
15
+ const { node, record, inlineRecordComponents } = Astro.props;
16
16
 
17
- const Component = inlineItemComponents?.[record.__typename];
17
+ const Component = inlineRecordComponents?.[record.__typename];
18
18
 
19
19
  if (!Component) {
20
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!`,
21
+ `The Structured Text document contains an 'inlineItem' node, but no component for rendering it is specified in the inlineRecordComponents prop!`,
22
22
  node,
23
23
  );
24
24
  }
@@ -5,23 +5,23 @@ import {
5
5
  type ItemLink,
6
6
  } from 'datocms-structured-text-utils';
7
7
 
8
- import type { ItemLinkComponents } from '../types';
8
+ import type { LinkToRecordComponents } from '../types';
9
9
 
10
10
  import { defaultMetaTransformer } from 'datocms-structured-text-generic-html-renderer';
11
11
 
12
12
  interface Props {
13
13
  node: ItemLink;
14
14
  record: DatocmsRecord;
15
- itemLinkComponents?: ItemLinkComponents<DatocmsRecord, DatocmsRecord>;
15
+ linkToRecordComponents?: LinkToRecordComponents<DatocmsRecord, DatocmsRecord>;
16
16
  }
17
17
 
18
- const { node, record, itemLinkComponents } = Astro.props;
18
+ const { node, record, linkToRecordComponents } = Astro.props;
19
19
 
20
- const Component = itemLinkComponents?.[record.__typename];
20
+ const Component = linkToRecordComponents?.[record.__typename];
21
21
 
22
22
  if (!Component) {
23
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!`,
24
+ `The Structured Text document contains an 'itemLink' node, but no component for rendering it is specified in the linkToRecordComponents prop!`,
25
25
  node,
26
26
  );
27
27
  }
@@ -1,56 +1,49 @@
1
1
  ---
2
- import type { Span } from 'datocms-structured-text-utils';
2
+ import type { Mark, Span } from 'datocms-structured-text-utils';
3
3
  import Lines from '../Lines.astro';
4
+ import type { MarkOverrides } from '../types';
4
5
 
5
6
  interface Props {
6
7
  node: Span;
8
+ markOverrides?: MarkOverrides;
7
9
  }
8
10
 
9
- const { node } = Astro.props;
11
+ const { node, markOverrides } = Astro.props;
10
12
 
11
13
  const { type, value, marks } = node;
12
14
 
13
15
  const [mark, ...otherMarks] = marks ?? [];
16
+
17
+ function markToComponent(mark: Mark) {
18
+ if (markOverrides && mark in markOverrides) {
19
+ return markOverrides[mark];
20
+ }
21
+
22
+ switch (mark) {
23
+ case 'emphasis':
24
+ return 'em';
25
+ case 'underline':
26
+ return 'u';
27
+ case 'strikethrough':
28
+ return 's';
29
+ case 'highlight':
30
+ return 'mark';
31
+ default:
32
+ return mark;
33
+ }
34
+ }
35
+
36
+ const MarkComponent = mark ? markToComponent(mark) : null;
14
37
  ---
15
38
 
16
39
  {
17
- !mark ? (
18
- <Lines lines={node.value.split(/\n/)} />
19
- ) : mark === 'emphasis' ? (
20
- <em>
21
- <Astro.self node={{ type, value, marks: otherMarks }}>
22
- <slot />
23
- </Astro.self>
24
- </em>
25
- ) : mark === 'highlight' ? (
26
- <mark>
27
- <Astro.self node={{ type, value, marks: otherMarks }}>
28
- <slot />
29
- </Astro.self>
30
- </mark>
31
- ) : mark === 'strikethrough' ? (
32
- <del>
40
+ MarkComponent ? (
41
+ <MarkComponent>
33
42
  <Astro.self node={{ type, value, marks: otherMarks }}>
34
43
  <slot />
35
44
  </Astro.self>
36
- </del>
37
- ) : mark === 'strong' ? (
38
- <strong>
39
- <Astro.self node={{ type, value, marks: otherMarks }}>
40
- <slot />
41
- </Astro.self>
42
- </strong>
43
- ) : mark === 'underline' ? (
44
- <u>
45
- <Astro.self node={{ type, value, marks: otherMarks }}>
46
- <slot />
47
- </Astro.self>
48
- </u>
49
- ) : mark === 'code' ? (
50
- <code>
51
- <Astro.self node={{ type, value, marks: otherMarks }}>
52
- <slot />
53
- </Astro.self>
54
- </code>
55
- ) : undefined
45
+ </MarkComponent>
46
+ ) : (
47
+ <Lines lines={node.value.split(/\n/)} />
48
+ )
56
49
  }
@@ -1,21 +1,23 @@
1
- import type { Record as DatocmsRecord, NodeType } from 'datocms-structured-text-utils';
1
+ import type { Record as DatocmsRecord, Mark, NodeType } from 'datocms-structured-text-utils';
2
2
 
3
3
  // biome-ignore lint/suspicious/noExplicitAny: <explanation>
4
- type AstroComponent = (props: any) => any;
4
+ export type AstroComponent = (props: any) => any;
5
5
 
6
6
  export type BlockComponents<R1 extends DatocmsRecord, R2 extends DatocmsRecord> = Record<
7
7
  R1['__typename'],
8
8
  AstroComponent
9
9
  >;
10
10
 
11
- export type ItemLinkComponents<R1 extends DatocmsRecord, R2 extends DatocmsRecord> = Record<
11
+ export type LinkToRecordComponents<R1 extends DatocmsRecord, R2 extends DatocmsRecord> = Record<
12
12
  R2['__typename'],
13
13
  AstroComponent
14
14
  >;
15
15
 
16
- export type InlineItemComponents<R1 extends DatocmsRecord, R2 extends DatocmsRecord> = Record<
16
+ export type InlineRecordComponents<R1 extends DatocmsRecord, R2 extends DatocmsRecord> = Record<
17
17
  R2['__typename'],
18
18
  AstroComponent
19
19
  >;
20
20
 
21
- export type Overrides = Record<NodeType, AstroComponent>;
21
+ export type NodeOverrides = Partial<Record<NodeType, AstroComponent>>;
22
+
23
+ export type MarkOverrides = Partial<Record<Mark, AstroComponent>>;