@storyblok/astro 9.0.12 → 10.0.0

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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  import options from 'virtual:storyblok-options';
3
- import { toCamelCase, type SbBlokData } from '@storyblok/astro';
3
+ import { toCamelCase, type SbBlokData } from '../';
4
4
  import type { AstroComponentFactory } from 'astro/runtime/server/index.js';
5
5
  import { storyblokComponents } from 'virtual:import-storyblok-components';
6
6
 
@@ -0,0 +1,14 @@
1
+ ---
2
+ import { type SbRichTextInput, type SbAstroRichTextRenderContext, normalizeNodes } from '../';
3
+ import RenderChildren from './richtext/RenderChildren.astro';
4
+
5
+ interface Props extends SbAstroRichTextRenderContext {
6
+ document: SbRichTextInput;
7
+ }
8
+
9
+ const { document, components, optimizeImage } = Astro.props;
10
+
11
+ const nodes = normalizeNodes(document);
12
+ ---
13
+
14
+ <RenderChildren nodes={nodes} options={{ components, optimizeImage }} />
@@ -0,0 +1,32 @@
1
+ ---
2
+ import {
3
+ attrsToHtmlString,
4
+ buildAstroAttrs,
5
+ resolveTag,
6
+ isSelfClosing,
7
+ type SbRichTextMark,
8
+ type SbRichTextNode,
9
+ } from '../../';
10
+ interface Props {
11
+ node: Exclude<SbRichTextNode, { type: 'text' }> | SbRichTextMark;
12
+ }
13
+ const { node } = Astro.props;
14
+
15
+ const Tag = resolveTag(node);
16
+ const processedAttrs = buildAstroAttrs(node.type, node?.attrs ?? {});
17
+ const selfClosing = Tag && isSelfClosing(Tag);
18
+ ---
19
+
20
+ {
21
+ Tag ? (
22
+ selfClosing ? (
23
+ <Fragment set:html={`<${Tag}${attrsToHtmlString(processedAttrs)}>`} />
24
+ ) : (
25
+ <Tag {...processedAttrs}>
26
+ <slot />
27
+ </Tag>
28
+ )
29
+ ) : (
30
+ <slot />
31
+ )
32
+ }
@@ -0,0 +1,26 @@
1
+ ---
2
+ import { type SbRichTextNode, type SbAstroRichTextRenderContext, groupLinkNodes } from '../../';
3
+ import RenderLinkGroup from './RenderLinkGroup.astro';
4
+ import RenderNode from './RenderNode.astro';
5
+
6
+ interface Props {
7
+ nodes: SbRichTextNode[];
8
+ options: SbAstroRichTextRenderContext;
9
+ }
10
+ const { nodes, options } = Astro.props;
11
+ const groups = groupLinkNodes(nodes);
12
+ ---
13
+
14
+ {
15
+ groups.map((group) =>
16
+ group.linkMark ? (
17
+ <RenderLinkGroup
18
+ nodes={group.nodes.filter((node) => node.type === 'text')}
19
+ linkMark={group.linkMark}
20
+ options={options}
21
+ />
22
+ ) : (
23
+ <RenderNode node={group.nodes[0]} options={options} />
24
+ ),
25
+ )
26
+ }
@@ -0,0 +1,24 @@
1
+ ---
2
+ import { type SbRichTextNode, type SbAstroRichTextRenderContext, buildStoryblokImage } from '../../';
3
+ import ElementTag from './ElementTag.astro';
4
+
5
+ type ImageNode = SbRichTextNode & { type: 'image' };
6
+ interface Props {
7
+ node: ImageNode;
8
+ options: SbAstroRichTextRenderContext;
9
+ }
10
+ const { node, options } = Astro.props;
11
+ const optimizedNode: ImageNode =
12
+ options.optimizeImage && node?.attrs?.src
13
+ ? {
14
+ ...node,
15
+ attrs: {
16
+ ...node.attrs,
17
+ ...buildStoryblokImage(node.attrs.src as string, options.optimizeImage),
18
+ },
19
+ type: 'image',
20
+ }
21
+ : node;
22
+ ---
23
+
24
+ <ElementTag node={optimizedNode} />
@@ -0,0 +1,31 @@
1
+ ---
2
+ import {
3
+ type SbRichTextTextNode,
4
+ type SbAstroRichTextRenderContext,
5
+ type SbRichTextMark,
6
+ isValidAstroComponent,
7
+ } from '../../';
8
+ import RenderLinkInner from './RenderLinkInner.astro';
9
+ import ElementTag from './ElementTag.astro';
10
+
11
+ interface Props {
12
+ nodes: SbRichTextTextNode[];
13
+ linkMark: SbRichTextMark & { type: 'link' };
14
+ options: SbAstroRichTextRenderContext;
15
+ }
16
+ const { nodes, linkMark, options } = Astro.props;
17
+ const components = options.components;
18
+ const Custom = components ? components[linkMark.type] : undefined;
19
+ ---
20
+
21
+ {
22
+ isValidAstroComponent(Custom) ? (
23
+ <Custom {...linkMark}>
24
+ <RenderLinkInner nodes={nodes} options={options} />
25
+ </Custom>
26
+ ) : (
27
+ <ElementTag node={linkMark}>
28
+ <RenderLinkInner nodes={nodes} options={options} />
29
+ </ElementTag>
30
+ )
31
+ }
@@ -0,0 +1,18 @@
1
+ ---
2
+ import type { SbAstroRichTextRenderContext, SbRichTextTextNode } from '../../';
3
+ import { getInnerMarks } from '../../';
4
+ import RenderTextNodeWithMarks from './RenderTextNodeWithMarks.astro';
5
+
6
+ interface Props {
7
+ nodes: SbRichTextTextNode[];
8
+ options: SbAstroRichTextRenderContext;
9
+ }
10
+ const { nodes, options } = Astro.props;
11
+ ---
12
+
13
+ {
14
+ nodes.map((node) => {
15
+ const innermarks = getInnerMarks(node);
16
+ return <RenderTextNodeWithMarks node={node} marks={innermarks} options={options} />;
17
+ })
18
+ }
@@ -0,0 +1,46 @@
1
+ ---
2
+ import {
3
+ type SbRichTextNode,
4
+ type SbAstroRichTextRenderContext,
5
+ isValidAstroComponent,
6
+ getStaticChildren,
7
+ } from '../../';
8
+ import StoryblokComponent from '../StoryblokComponent.astro';
9
+ import RenderChildren from './RenderChildren.astro';
10
+ import ElementTag from './ElementTag.astro';
11
+ import RenderImage from './RenderImage.astro';
12
+ import RenderStaticChildren from './RenderStaticChildren.astro';
13
+ import RenderTable from './RenderTable.astro';
14
+ import RenderTextNodeWithMarks from './RenderTextNodeWithMarks.astro';
15
+
16
+ interface Props {
17
+ node: SbRichTextNode;
18
+ options: SbAstroRichTextRenderContext;
19
+ }
20
+ const { node, options } = Astro.props;
21
+ const components = options.components;
22
+ const Custom = components && node.type !== 'text' ? components[node.type] : undefined;
23
+ ---
24
+
25
+ {
26
+ node.type === 'text' ? (
27
+ <RenderTextNodeWithMarks node={node} marks={node.marks} options={options} />
28
+ ) : isValidAstroComponent(Custom) ? (
29
+ <Custom {...node} context={options}>
30
+ {node.content && <RenderChildren nodes={node.content} options={options} />}
31
+ </Custom>
32
+ ) : node.type === 'image' ? (
33
+ <RenderImage node={node} options={options} />
34
+ ) : node.type === 'blok' ? (
35
+ <Fragment>
36
+ {Array.isArray(node.attrs?.body) &&
37
+ node.attrs.body.map((blok, index) => <StoryblokComponent blok={blok} key={blok._uid || index} />)}
38
+ </Fragment>
39
+ ) : node.type === 'table' ? (
40
+ <RenderTable node={node} options={options} />
41
+ ) : getStaticChildren(node) ? (
42
+ <RenderStaticChildren node={node} options={options} />
43
+ ) : (
44
+ <ElementTag node={node}>{node.content && <RenderChildren nodes={node.content} options={options} />}</ElementTag>
45
+ )
46
+ }
@@ -0,0 +1,23 @@
1
+ ---
2
+ import { type SbAstroRichTextRenderContext, type SbRichTextNode, getStaticChildren, resolveTag } from '../../';
3
+ import RenderChildren from './RenderChildren.astro';
4
+ import RenderStaticStructure from './RenderStaticStructure.astro';
5
+
6
+ interface Props {
7
+ node: Exclude<SbRichTextNode, { type: 'text' }>;
8
+ options: SbAstroRichTextRenderContext;
9
+ }
10
+ const { node, options } = Astro.props;
11
+ const staticChildren = getStaticChildren(node);
12
+ const OuterTag = resolveTag(node);
13
+ ---
14
+
15
+ {
16
+ staticChildren && OuterTag ? (
17
+ <OuterTag>
18
+ <RenderStaticStructure type={node.type} specs={staticChildren} parentAttrs={node.attrs}>
19
+ {node.content && <RenderChildren nodes={node.content} options={options} />}
20
+ </RenderStaticStructure>
21
+ </OuterTag>
22
+ ) : null
23
+ }
@@ -0,0 +1,35 @@
1
+ ---
2
+ import { attrsToHtmlString, buildAstroAttrs, isSelfClosing, type RenderSpec, type SbRichTextElement } from '../../';
3
+
4
+ interface Props {
5
+ type: SbRichTextElement;
6
+ specs: readonly RenderSpec[];
7
+ parentAttrs?: Record<string, unknown>;
8
+ }
9
+
10
+ const { type, specs, parentAttrs } = Astro.props;
11
+ ---
12
+
13
+ {
14
+ specs.map((spec) => {
15
+ const { tag, children, attrs: specAttrs } = spec;
16
+ const Tag = tag;
17
+ const mergedAttrs = { ...specAttrs, ...parentAttrs };
18
+ const processedAttrs = buildAstroAttrs(type, mergedAttrs);
19
+
20
+ if (isSelfClosing(Tag)) {
21
+ return <Fragment set:html={`<${tag}${attrsToHtmlString(processedAttrs)}>`} />;
22
+ }
23
+ return (
24
+ <Tag {...processedAttrs}>
25
+ {children ? (
26
+ <Astro.self type={type} specs={children} parentAttrs={parentAttrs}>
27
+ <slot />
28
+ </Astro.self>
29
+ ) : (
30
+ <slot />
31
+ )}
32
+ </Tag>
33
+ );
34
+ })
35
+ }
@@ -0,0 +1,20 @@
1
+ ---
2
+ import { type SbRichTextNode, type SbAstroRichTextRenderContext, splitTableRows } from '../../';
3
+ import ElementTag from './ElementTag.astro';
4
+ import RenderNode from './RenderNode.astro';
5
+ interface Props {
6
+ node: SbRichTextNode & { type: 'table' };
7
+ options: SbAstroRichTextRenderContext;
8
+ }
9
+ const { node, options } = Astro.props;
10
+ const { headerRows, bodyRows } = splitTableRows(node.content);
11
+ ---
12
+
13
+ <ElementTag node={node}>
14
+ {
15
+ headerRows.length > 0 && (<thead>{headerRows.map((row) => <RenderNode node={row} options={options} />)}</thead>)
16
+ }
17
+ {
18
+ bodyRows.length > 0 && (<tbody>{bodyRows.map((row) => <RenderNode node={row} options={options} />)}</tbody>)
19
+ }
20
+ </ElementTag>
@@ -0,0 +1,34 @@
1
+ ---
2
+ import {
3
+ type SbRichTextTextNode,
4
+ type SbRichTextMark,
5
+ type SbAstroRichTextRenderContext,
6
+ isValidAstroComponent,
7
+ } from '../../';
8
+ import ElementTag from './ElementTag.astro';
9
+
10
+ interface Props {
11
+ node: SbRichTextTextNode;
12
+ marks?: SbRichTextMark[];
13
+ options: SbAstroRichTextRenderContext;
14
+ }
15
+ const { node, marks = [], options } = Astro.props;
16
+ const reversedMarks = [...marks].reverse();
17
+ const [mark, ...rest] = reversedMarks;
18
+ const components = options.components;
19
+ const MarkComponent = mark && components ? components[mark.type] : undefined;
20
+ ---
21
+
22
+ {
23
+ reversedMarks.length === 0 ? (
24
+ node.text
25
+ ) : isValidAstroComponent(MarkComponent) ? (
26
+ <MarkComponent {...mark}>
27
+ <Astro.self node={node} marks={rest} options={options} />
28
+ </MarkComponent>
29
+ ) : (
30
+ <ElementTag node={mark}>
31
+ <Astro.self node={node} marks={rest} options={options} />
32
+ </ElementTag>
33
+ )
34
+ }
package/dist/index.d.ts CHANGED
@@ -6,7 +6,10 @@ export type { IntegrationOptions } from './lib/storyblok-integration';
6
6
  export { handleStoryblokMessage } from './live-preview/handleStoryblokMessage';
7
7
  export * from './types';
8
8
  export { isEditorRequest } from './utils/isEditorRequest';
9
+ export { buildAstroAttrs, isValidAstroComponent, type SbAstroRichTextComponentMap, type SbAstroRichTextProps, type SbAstroRichTextRenderContext } from './utils/richtext-helpers';
9
10
  export { toCamelCase } from './utils/toCamelCase';
10
- export { loadStoryblokBridge, renderRichText, richTextResolver, segmentStoryblokRichText, storyblokEditable, } from '@storyblok/js';
11
11
  export { storyblokIntegration as storyblok };
12
- export { apiPlugin, storyblokInit } from '@storyblok/js';
12
+ export { apiPlugin, loadStoryblokBridge, storyblokEditable, storyblokInit, } from '@storyblok/js';
13
+ export { buildStoryblokImage, renderRichText, splitTableRows } from '@storyblok/richtext';
14
+ export type { SbRichTextDoc, SbRichTextImageOptions, SbRichTextMark, SbRichTextNode, SbRichTextProps, SbRichTextRenderContext, } from '@storyblok/richtext';
15
+ export { attrsToHtmlString, getInnerMarks, getStaticChildren, groupLinkNodes, isSelfClosing, normalizeNodes, processAttrs, type RenderSpec, resolveTag, type SbRichTextElement, type SbRichTextInput, type SbRichTextTextNode, styleToString } from '@storyblok/richtext';