@airdraft/react-content 0.1.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.
- package/dist/blog/PostCard.d.ts +61 -0
- package/dist/blog/PostCard.d.ts.map +1 -0
- package/dist/blog/PostCard.js +44 -0
- package/dist/blog/PostCard.js.map +1 -0
- package/dist/blog/PostDetail.d.ts +68 -0
- package/dist/blog/PostDetail.d.ts.map +1 -0
- package/dist/blog/PostDetail.js +47 -0
- package/dist/blog/PostDetail.js.map +1 -0
- package/dist/blog/index.d.ts +5 -0
- package/dist/blog/index.d.ts.map +1 -0
- package/dist/blog/index.js +3 -0
- package/dist/blog/index.js.map +1 -0
- package/dist/compounds/EntryCard.d.ts +44 -0
- package/dist/compounds/EntryCard.d.ts.map +1 -0
- package/dist/compounds/EntryCard.js +65 -0
- package/dist/compounds/EntryCard.js.map +1 -0
- package/dist/compounds/EntryDetail.d.ts +45 -0
- package/dist/compounds/EntryDetail.d.ts.map +1 -0
- package/dist/compounds/EntryDetail.js +63 -0
- package/dist/compounds/EntryDetail.js.map +1 -0
- package/dist/compounds/index.d.ts +5 -0
- package/dist/compounds/index.d.ts.map +1 -0
- package/dist/compounds/index.js +3 -0
- package/dist/compounds/index.js.map +1 -0
- package/dist/fields/AuthorByline.d.ts +26 -0
- package/dist/fields/AuthorByline.d.ts.map +1 -0
- package/dist/fields/AuthorByline.js +19 -0
- package/dist/fields/AuthorByline.js.map +1 -0
- package/dist/fields/BodyField.d.ts +22 -0
- package/dist/fields/BodyField.d.ts.map +1 -0
- package/dist/fields/BodyField.js +23 -0
- package/dist/fields/BodyField.js.map +1 -0
- package/dist/fields/DateField.d.ts +15 -0
- package/dist/fields/DateField.d.ts.map +1 -0
- package/dist/fields/DateField.js +17 -0
- package/dist/fields/DateField.js.map +1 -0
- package/dist/fields/ImageField.d.ts +32 -0
- package/dist/fields/ImageField.d.ts.map +1 -0
- package/dist/fields/ImageField.js +21 -0
- package/dist/fields/ImageField.js.map +1 -0
- package/dist/fields/TagList.d.ts +14 -0
- package/dist/fields/TagList.d.ts.map +1 -0
- package/dist/fields/TagList.js +12 -0
- package/dist/fields/TagList.js.map +1 -0
- package/dist/fields/index.d.ts +11 -0
- package/dist/fields/index.d.ts.map +1 -0
- package/dist/fields/index.js +6 -0
- package/dist/fields/index.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/next/AirdraftImage.d.ts +24 -0
- package/dist/next/AirdraftImage.d.ts.map +1 -0
- package/dist/next/AirdraftImage.js +26 -0
- package/dist/next/AirdraftImage.js.map +1 -0
- package/dist/next/index.d.ts +3 -0
- package/dist/next/index.d.ts.map +1 -0
- package/dist/next/index.js +2 -0
- package/dist/next/index.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { ReactNode, ComponentProps } from 'react';
|
|
2
|
+
import type { Entry } from '@airdraft/core';
|
|
3
|
+
import { type ExpandedAuthor } from '../fields/AuthorByline.js';
|
|
4
|
+
interface PostData {
|
|
5
|
+
title?: string;
|
|
6
|
+
excerpt?: string;
|
|
7
|
+
cover?: string;
|
|
8
|
+
cover_url?: string;
|
|
9
|
+
cover_media?: {
|
|
10
|
+
url?: string;
|
|
11
|
+
width?: number;
|
|
12
|
+
height?: number;
|
|
13
|
+
};
|
|
14
|
+
tags?: string[];
|
|
15
|
+
publishedAt?: string;
|
|
16
|
+
authors?: string | string[] | ExpandedAuthor[];
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
}
|
|
19
|
+
type PostEntry = Entry<PostData>;
|
|
20
|
+
declare function PostMeta({ post, className }: {
|
|
21
|
+
post: PostEntry;
|
|
22
|
+
className?: string;
|
|
23
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
export interface PostCardProps extends ComponentProps<'article'> {
|
|
25
|
+
post: PostEntry;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Blog-recipe card component for a standard `posts` collection entry.
|
|
29
|
+
*
|
|
30
|
+
* Renders: Cover → Title → Excerpt → Tags → Meta (date + author).
|
|
31
|
+
* Override using compound sub-components for surgical control.
|
|
32
|
+
*
|
|
33
|
+
* RSC-compatible — no `"use client"`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function PostCard({ post, className, ...rest }: PostCardProps): ReactNode;
|
|
36
|
+
export declare namespace PostCard {
|
|
37
|
+
var Root: ({ className, children }: {
|
|
38
|
+
className?: string;
|
|
39
|
+
children?: ReactNode;
|
|
40
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
41
|
+
var Cover: ({ post, className }: {
|
|
42
|
+
post: PostEntry;
|
|
43
|
+
className?: string;
|
|
44
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
45
|
+
var Title: ({ className, children }: {
|
|
46
|
+
className?: string;
|
|
47
|
+
children?: ReactNode;
|
|
48
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
49
|
+
var Excerpt: ({ className, children }: {
|
|
50
|
+
className?: string;
|
|
51
|
+
children?: ReactNode;
|
|
52
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
53
|
+
var Tags: ({ post, className, tagClassName }: {
|
|
54
|
+
post: PostEntry;
|
|
55
|
+
className?: string;
|
|
56
|
+
tagClassName?: string;
|
|
57
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
58
|
+
var Meta: typeof PostMeta;
|
|
59
|
+
}
|
|
60
|
+
export {};
|
|
61
|
+
//# sourceMappingURL=PostCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostCard.d.ts","sourceRoot":"","sources":["../../src/blog/PostCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAI3C,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAM7E,UAAU,QAAQ;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC/D,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,cAAc,EAAE,CAAA;IAC9C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,KAAK,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAA;AA0BhC,iBAAS,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,2CAS7E;AAMD,MAAM,WAAW,aAAc,SAAQ,cAAc,CAAC,SAAS,CAAC;IAC9D,IAAI,EAAE,SAAS,CAAA;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa,GAAG,SAAS,CAU/E;yBAVe,QAAQ;wCA/Ce;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;KAAE;qCAI/C;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;yCAInC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;KAAE;2CAI1C;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;KAAE;kDAIrC;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ImageField } from '../fields/ImageField.js';
|
|
3
|
+
import { TagList } from '../fields/TagList.js';
|
|
4
|
+
import { DateField } from '../fields/DateField.js';
|
|
5
|
+
import { AuthorByline } from '../fields/AuthorByline.js';
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Sub-component primitives (thin wrappers matching the agreed API)
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
function Root({ className, children }) {
|
|
10
|
+
return _jsx("article", { className: className, children: children });
|
|
11
|
+
}
|
|
12
|
+
function Cover({ post, className }) {
|
|
13
|
+
return _jsx(ImageField, { field: "cover", entry: post, className: className, alt: post.data.title ?? '' });
|
|
14
|
+
}
|
|
15
|
+
function Title({ className, children }) {
|
|
16
|
+
return _jsx("h2", { className: className, children: children });
|
|
17
|
+
}
|
|
18
|
+
function Excerpt({ className, children }) {
|
|
19
|
+
return _jsx("p", { className: className, children: children });
|
|
20
|
+
}
|
|
21
|
+
function Tags({ post, className, tagClassName }) {
|
|
22
|
+
return _jsx(TagList, { tags: post.data.tags ?? [], className: className, tagClassName: tagClassName });
|
|
23
|
+
}
|
|
24
|
+
function PostMeta({ post, className }) {
|
|
25
|
+
return (_jsxs("div", { className: className, children: [post.data.publishedAt && _jsx(DateField, { value: post.data.publishedAt }), post.data.authors && (_jsx(AuthorByline, { authors: post.data.authors }))] }));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Blog-recipe card component for a standard `posts` collection entry.
|
|
29
|
+
*
|
|
30
|
+
* Renders: Cover → Title → Excerpt → Tags → Meta (date + author).
|
|
31
|
+
* Override using compound sub-components for surgical control.
|
|
32
|
+
*
|
|
33
|
+
* RSC-compatible — no `"use client"`.
|
|
34
|
+
*/
|
|
35
|
+
export function PostCard({ post, className, ...rest }) {
|
|
36
|
+
return (_jsxs("article", { className: className, ...rest, children: [_jsx(Cover, { post: post }), post.data.title && _jsx(Title, { children: post.data.title }), post.data.excerpt && _jsx(Excerpt, { children: post.data.excerpt }), _jsx(Tags, { post: post }), _jsx(PostMeta, { post: post })] }));
|
|
37
|
+
}
|
|
38
|
+
PostCard.Root = Root;
|
|
39
|
+
PostCard.Cover = Cover;
|
|
40
|
+
PostCard.Title = Title;
|
|
41
|
+
PostCard.Excerpt = Excerpt;
|
|
42
|
+
PostCard.Tags = Tags;
|
|
43
|
+
PostCard.Meta = PostMeta;
|
|
44
|
+
//# sourceMappingURL=PostCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostCard.js","sourceRoot":"","sources":["../../src/blog/PostCard.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAClD,OAAO,EAAE,YAAY,EAAuB,MAAM,2BAA2B,CAAA;AAoB7E,8EAA8E;AAC9E,mEAAmE;AACnE,8EAA8E;AAE9E,SAAS,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAgD;IACjF,OAAO,kBAAS,SAAS,EAAE,SAAS,YAAG,QAAQ,GAAW,CAAA;AAC5D,CAAC;AAED,SAAS,KAAK,CAAC,EAAE,IAAI,EAAE,SAAS,EAA2C;IACzE,OAAO,KAAC,UAAU,IAAC,KAAK,EAAC,OAAO,EAAC,KAAK,EAAE,IAAa,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,GAAI,CAAA;AAC7G,CAAC;AAED,SAAS,KAAK,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAgD;IAClF,OAAO,aAAI,SAAS,EAAE,SAAS,YAAG,QAAQ,GAAM,CAAA;AAClD,CAAC;AAED,SAAS,OAAO,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAgD;IACpF,OAAO,YAAG,SAAS,EAAE,SAAS,YAAG,QAAQ,GAAK,CAAA;AAChD,CAAC;AAED,SAAS,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAkE;IAC7G,OAAO,KAAC,OAAO,IAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,GAAI,CAAA;AAClG,CAAC;AAED,SAAS,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAA2C;IAC5E,OAAO,CACL,eAAK,SAAS,EAAE,SAAS,aACtB,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,KAAC,SAAS,IAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,GAAI,EACpE,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CACpB,KAAC,YAAY,IAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,OAA+C,GAAI,CACrF,IACG,CACP,CAAA;AACH,CAAC;AAUD;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,EAAiB;IAClE,OAAO,CACL,mBAAS,SAAS,EAAE,SAAS,KAAM,IAAI,aACrC,KAAC,KAAK,IAAC,IAAI,EAAE,IAAI,GAAI,EACpB,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,KAAC,KAAK,cAAE,IAAI,CAAC,IAAI,CAAC,KAAK,GAAS,EACnD,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,KAAC,OAAO,cAAE,IAAI,CAAC,IAAI,CAAC,OAAO,GAAW,EAC5D,KAAC,IAAI,IAAC,IAAI,EAAE,IAAI,GAAI,EACpB,KAAC,QAAQ,IAAC,IAAI,EAAE,IAAI,GAAI,IAChB,CACX,CAAA;AACH,CAAC;AAED,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAA;AACpB,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAA;AACtB,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAA;AACtB,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAA;AAC1B,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAA;AACpB,QAAQ,CAAC,IAAI,GAAG,QAAQ,CAAA"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { ReactNode, ComponentProps } from 'react';
|
|
2
|
+
import type { Entry } from '@airdraft/core';
|
|
3
|
+
import { type ExpandedAuthor } from '../fields/AuthorByline.js';
|
|
4
|
+
interface PostData {
|
|
5
|
+
title?: string;
|
|
6
|
+
body?: string;
|
|
7
|
+
excerpt?: string;
|
|
8
|
+
cover?: string;
|
|
9
|
+
cover_url?: string;
|
|
10
|
+
cover_media?: {
|
|
11
|
+
url?: string;
|
|
12
|
+
width?: number;
|
|
13
|
+
height?: number;
|
|
14
|
+
};
|
|
15
|
+
tags?: string[];
|
|
16
|
+
publishedAt?: string;
|
|
17
|
+
authors?: string | string[] | ExpandedAuthor[];
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
}
|
|
20
|
+
type PostEntry = Entry<PostData>;
|
|
21
|
+
declare function PostMeta({ post, className }: {
|
|
22
|
+
post: PostEntry;
|
|
23
|
+
className?: string;
|
|
24
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
export interface PostDetailProps extends ComponentProps<'article'> {
|
|
26
|
+
post: PostEntry;
|
|
27
|
+
/** Field type of `body`. Defaults to `'rich-text'` (Markdown). */
|
|
28
|
+
bodyType?: 'text' | 'rich-text';
|
|
29
|
+
/** Override the body renderer entirely. */
|
|
30
|
+
renderBody?: (text: string) => ReactNode;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Blog-recipe full-page detail component for a standard `posts` entry.
|
|
34
|
+
*
|
|
35
|
+
* Renders: Cover → Header (title + meta) → Body → Tags.
|
|
36
|
+
* Override using compound sub-components for surgical control.
|
|
37
|
+
*
|
|
38
|
+
* RSC-compatible — no `"use client"`.
|
|
39
|
+
*/
|
|
40
|
+
export declare function PostDetail({ post, bodyType, renderBody, className, ...rest }: PostDetailProps): ReactNode;
|
|
41
|
+
export declare namespace PostDetail {
|
|
42
|
+
var Root: ({ className, children }: {
|
|
43
|
+
className?: string;
|
|
44
|
+
children?: ReactNode;
|
|
45
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
46
|
+
var Cover: ({ post, className }: {
|
|
47
|
+
post: PostEntry;
|
|
48
|
+
className?: string;
|
|
49
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
50
|
+
var Header: ({ className, children }: {
|
|
51
|
+
className?: string;
|
|
52
|
+
children?: ReactNode;
|
|
53
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
54
|
+
var Body: ({ post, type, className, render, }: {
|
|
55
|
+
post: PostEntry;
|
|
56
|
+
type?: "text" | "rich-text";
|
|
57
|
+
className?: string;
|
|
58
|
+
render?: (text: string) => ReactNode;
|
|
59
|
+
}) => import("react/jsx-runtime").JSX.Element | null;
|
|
60
|
+
var Tags: ({ post, className, tagClassName }: {
|
|
61
|
+
post: PostEntry;
|
|
62
|
+
className?: string;
|
|
63
|
+
tagClassName?: string;
|
|
64
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
65
|
+
var Meta: typeof PostMeta;
|
|
66
|
+
}
|
|
67
|
+
export {};
|
|
68
|
+
//# sourceMappingURL=PostDetail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostDetail.d.ts","sourceRoot":"","sources":["../../src/blog/PostDetail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAK3C,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAM7E,UAAU,QAAQ;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC/D,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,cAAc,EAAE,CAAA;IAC9C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,KAAK,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAA;AAqChC,iBAAS,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,2CAS7E;AAMD,MAAM,WAAW,eAAgB,SAAQ,cAAc,CAAC,SAAS,CAAC;IAChE,IAAI,EAAE,SAAS,CAAA;IACf,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IAC/B,2CAA2C;IAC3C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAA;CACzC;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,QAAsB,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,eAAe,GAAG,SAAS,CAYvH;yBAZe,UAAU;wCA9Da;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;KAAE;qCAI/C;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;0CAIlC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;KAAE;mDASlF;QACD,IAAI,EAAE,SAAS,CAAA;QACf,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;QAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAA;KACrC;kDAKgD;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ImageField } from '../fields/ImageField.js';
|
|
3
|
+
import { BodyField } from '../fields/BodyField.js';
|
|
4
|
+
import { TagList } from '../fields/TagList.js';
|
|
5
|
+
import { DateField } from '../fields/DateField.js';
|
|
6
|
+
import { AuthorByline } from '../fields/AuthorByline.js';
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Sub-component primitives
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
function Root({ className, children }) {
|
|
11
|
+
return _jsx("article", { className: className, children: children });
|
|
12
|
+
}
|
|
13
|
+
function Cover({ post, className }) {
|
|
14
|
+
return _jsx(ImageField, { field: "cover", entry: post, className: className, alt: post.data.title ?? '' });
|
|
15
|
+
}
|
|
16
|
+
function Header({ className, children }) {
|
|
17
|
+
return _jsx("header", { className: className, children: children });
|
|
18
|
+
}
|
|
19
|
+
function Body({ post, type = 'rich-text', className, render, }) {
|
|
20
|
+
if (!post.data.body)
|
|
21
|
+
return null;
|
|
22
|
+
return _jsx(BodyField, { value: post.data.body, type: type, className: className, render: render });
|
|
23
|
+
}
|
|
24
|
+
function Tags({ post, className, tagClassName }) {
|
|
25
|
+
return _jsx(TagList, { tags: post.data.tags ?? [], className: className, tagClassName: tagClassName });
|
|
26
|
+
}
|
|
27
|
+
function PostMeta({ post, className }) {
|
|
28
|
+
return (_jsxs("div", { className: className, children: [post.data.publishedAt && _jsx(DateField, { value: post.data.publishedAt }), post.data.authors && (_jsx(AuthorByline, { authors: post.data.authors }))] }));
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Blog-recipe full-page detail component for a standard `posts` entry.
|
|
32
|
+
*
|
|
33
|
+
* Renders: Cover → Header (title + meta) → Body → Tags.
|
|
34
|
+
* Override using compound sub-components for surgical control.
|
|
35
|
+
*
|
|
36
|
+
* RSC-compatible — no `"use client"`.
|
|
37
|
+
*/
|
|
38
|
+
export function PostDetail({ post, bodyType = 'rich-text', renderBody, className, ...rest }) {
|
|
39
|
+
return (_jsxs("article", { className: className, ...rest, children: [_jsx(Cover, { post: post }), _jsxs(Header, { children: [post.data.title && _jsx("h1", { children: post.data.title }), _jsx(PostMeta, { post: post })] }), _jsx(Body, { post: post, type: bodyType, render: renderBody }), _jsx(Tags, { post: post })] }));
|
|
40
|
+
}
|
|
41
|
+
PostDetail.Root = Root;
|
|
42
|
+
PostDetail.Cover = Cover;
|
|
43
|
+
PostDetail.Header = Header;
|
|
44
|
+
PostDetail.Body = Body;
|
|
45
|
+
PostDetail.Tags = Tags;
|
|
46
|
+
PostDetail.Meta = PostMeta;
|
|
47
|
+
//# sourceMappingURL=PostDetail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostDetail.js","sourceRoot":"","sources":["../../src/blog/PostDetail.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/blog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/blog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAGxC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ReactNode, ComponentProps } from 'react';
|
|
2
|
+
import type { Entry, CollectionConfig } from '@airdraft/core';
|
|
3
|
+
export interface EntryCardProps extends ComponentProps<'article'> {
|
|
4
|
+
entry: Entry;
|
|
5
|
+
collection: CollectionConfig;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Generic schema-driven card component.
|
|
9
|
+
*
|
|
10
|
+
* Renders: Cover → Title → Excerpt → Tags → Meta (date).
|
|
11
|
+
* Override via compound sub-components for surgical control.
|
|
12
|
+
*
|
|
13
|
+
* RSC-compatible — no `"use client"`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function EntryCard({ entry, collection, className, ...rest }: EntryCardProps): ReactNode;
|
|
16
|
+
export declare namespace EntryCard {
|
|
17
|
+
var Root: ({ className, children }: {
|
|
18
|
+
className?: string;
|
|
19
|
+
children?: ReactNode;
|
|
20
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
var Cover: ({ entry, field, className, }: {
|
|
22
|
+
entry: Entry;
|
|
23
|
+
field?: string;
|
|
24
|
+
className?: string;
|
|
25
|
+
}) => import("react/jsx-runtime").JSX.Element | null;
|
|
26
|
+
var Title: ({ className, children }: {
|
|
27
|
+
className?: string;
|
|
28
|
+
children?: ReactNode;
|
|
29
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
var Excerpt: ({ className, children }: {
|
|
31
|
+
className?: string;
|
|
32
|
+
children?: ReactNode;
|
|
33
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
var Tags: ({ tags, className, tagClassName }: {
|
|
35
|
+
tags?: string[];
|
|
36
|
+
className?: string;
|
|
37
|
+
tagClassName?: string;
|
|
38
|
+
}) => import("react/jsx-runtime").JSX.Element | null;
|
|
39
|
+
var Meta: ({ className, children }: {
|
|
40
|
+
className?: string;
|
|
41
|
+
children?: ReactNode;
|
|
42
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=EntryCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntryCard.d.ts","sourceRoot":"","sources":["../../src/compounds/EntryCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAoD7D,MAAM,WAAW,cAAe,SAAQ,cAAc,CAAC,SAAS,CAAC;IAC/D,KAAK,EAAE,KAAK,CAAA;IACZ,UAAU,EAAE,gBAAgB,CAAA;CAC7B;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,cAAc,GAAG,SAAS,CA8C9F;yBA9Ce,SAAS;wCAtDc;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;KAAE;8CAQhF;QACD,KAAK,EAAE,KAAK,CAAA;QACZ,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,SAAS,CAAC,EAAE,MAAM,CAAA;KACnB;yCAQuC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;KAAE;2CAI1C;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;KAAE;kDAIrC;QAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE;wCAKxE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;KAAE"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ImageField } from '../fields/ImageField.js';
|
|
3
|
+
import { TagList } from '../fields/TagList.js';
|
|
4
|
+
import { DateField } from '../fields/DateField.js';
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Sub-component primitives
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
function Root({ className, children }) {
|
|
9
|
+
return _jsx("article", { className: className, children: children });
|
|
10
|
+
}
|
|
11
|
+
function Cover({ entry, field = 'cover', className, }) {
|
|
12
|
+
const data = entry.data;
|
|
13
|
+
// Detect the first image field in the entry if 'cover' isn't present
|
|
14
|
+
const imageField = data[field] !== undefined || data[`${field}_media`] !== undefined ? field : undefined;
|
|
15
|
+
if (!imageField)
|
|
16
|
+
return null;
|
|
17
|
+
return _jsx(ImageField, { field: imageField, entry: entry, className: className, alt: "" });
|
|
18
|
+
}
|
|
19
|
+
function Title({ className, children }) {
|
|
20
|
+
return _jsx("h2", { className: className, children: children });
|
|
21
|
+
}
|
|
22
|
+
function Excerpt({ className, children }) {
|
|
23
|
+
return _jsx("p", { className: className, children: children });
|
|
24
|
+
}
|
|
25
|
+
function Tags({ tags, className, tagClassName }) {
|
|
26
|
+
if (!tags?.length)
|
|
27
|
+
return null;
|
|
28
|
+
return _jsx(TagList, { tags: tags, className: className, tagClassName: tagClassName });
|
|
29
|
+
}
|
|
30
|
+
function Meta({ className, children }) {
|
|
31
|
+
return _jsx("div", { className: className, children: children });
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Generic schema-driven card component.
|
|
35
|
+
*
|
|
36
|
+
* Renders: Cover → Title → Excerpt → Tags → Meta (date).
|
|
37
|
+
* Override via compound sub-components for surgical control.
|
|
38
|
+
*
|
|
39
|
+
* RSC-compatible — no `"use client"`.
|
|
40
|
+
*/
|
|
41
|
+
export function EntryCard({ entry, collection, className, ...rest }) {
|
|
42
|
+
const data = entry.data;
|
|
43
|
+
// Discover first image field from schema
|
|
44
|
+
const imageFieldName = Object.entries(collection.fields).find(([, f]) => f.type === 'image')?.[0];
|
|
45
|
+
// Discover title-like string field
|
|
46
|
+
const titleFieldName = Object.keys(collection.fields).find((k) => ['title', 'name', 'heading', 'label'].includes(k));
|
|
47
|
+
// Discover excerpt-like text field
|
|
48
|
+
const excerptFieldName = Object.keys(collection.fields).find((k) => ['excerpt', 'description', 'summary'].includes(k));
|
|
49
|
+
// Discover tags / multiselect field
|
|
50
|
+
const tagsFieldName = Object.entries(collection.fields).find(([, f]) => f.type === 'multiselect' || f.type === 'list')?.[0];
|
|
51
|
+
// Discover date field
|
|
52
|
+
const dateFieldName = Object.entries(collection.fields).find(([, f]) => f.type === 'date' || f.type === 'datetime')?.[0];
|
|
53
|
+
const title = titleFieldName ? data[titleFieldName] : undefined;
|
|
54
|
+
const excerpt = excerptFieldName ? data[excerptFieldName] : undefined;
|
|
55
|
+
const tags = tagsFieldName ? data[tagsFieldName] : undefined;
|
|
56
|
+
const dateValue = dateFieldName ? data[dateFieldName] : undefined;
|
|
57
|
+
return (_jsxs("article", { className: className, ...rest, children: [imageFieldName && _jsx(Cover, { entry: entry, field: imageFieldName }), title && _jsx(Title, { children: title }), excerpt && _jsx(Excerpt, { children: excerpt }), tags && _jsx(Tags, { tags: tags }), dateValue && (_jsx(Meta, { children: _jsx(DateField, { value: dateValue }) }))] }));
|
|
58
|
+
}
|
|
59
|
+
EntryCard.Root = Root;
|
|
60
|
+
EntryCard.Cover = Cover;
|
|
61
|
+
EntryCard.Title = Title;
|
|
62
|
+
EntryCard.Excerpt = Excerpt;
|
|
63
|
+
EntryCard.Tags = Tags;
|
|
64
|
+
EntryCard.Meta = Meta;
|
|
65
|
+
//# sourceMappingURL=EntryCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntryCard.js","sourceRoot":"","sources":["../../src/compounds/EntryCard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ReactNode, ComponentProps } from 'react';
|
|
2
|
+
import type { Entry, CollectionConfig } from '@airdraft/core';
|
|
3
|
+
export interface EntryDetailProps extends ComponentProps<'article'> {
|
|
4
|
+
entry: Entry;
|
|
5
|
+
collection: CollectionConfig;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Generic schema-driven detail / full-page view component.
|
|
9
|
+
*
|
|
10
|
+
* Renders: Cover → Header (title + date) → Body → Tags.
|
|
11
|
+
* Override via compound sub-components for surgical control.
|
|
12
|
+
*
|
|
13
|
+
* RSC-compatible — no `"use client"`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function EntryDetail({ entry, collection, className, ...rest }: EntryDetailProps): ReactNode;
|
|
16
|
+
export declare namespace EntryDetail {
|
|
17
|
+
var Root: ({ className, children }: {
|
|
18
|
+
className?: string;
|
|
19
|
+
children?: ReactNode;
|
|
20
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
var Cover: ({ entry, field, className }: {
|
|
22
|
+
entry: Entry;
|
|
23
|
+
field?: string;
|
|
24
|
+
className?: string;
|
|
25
|
+
}) => import("react/jsx-runtime").JSX.Element | null;
|
|
26
|
+
var Header: ({ className, children }: {
|
|
27
|
+
className?: string;
|
|
28
|
+
children?: ReactNode;
|
|
29
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
var Body: ({ value, type, className, }: {
|
|
31
|
+
value?: string;
|
|
32
|
+
type?: "text" | "rich-text";
|
|
33
|
+
className?: string;
|
|
34
|
+
}) => import("react/jsx-runtime").JSX.Element | null;
|
|
35
|
+
var Tags: ({ tags, className, tagClassName }: {
|
|
36
|
+
tags?: string[];
|
|
37
|
+
className?: string;
|
|
38
|
+
tagClassName?: string;
|
|
39
|
+
}) => import("react/jsx-runtime").JSX.Element | null;
|
|
40
|
+
var Meta: ({ className, children }: {
|
|
41
|
+
className?: string;
|
|
42
|
+
children?: ReactNode;
|
|
43
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=EntryDetail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntryDetail.d.ts","sourceRoot":"","sources":["../../src/compounds/EntryDetail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAmD7D,MAAM,WAAW,gBAAiB,SAAQ,cAAc,CAAC,SAAS,CAAC;IACjE,KAAK,EAAE,KAAK,CAAA;IACZ,UAAU,EAAE,gBAAgB,CAAA;CAC7B;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,gBAAgB,GAAG,SAAS,CAuClG;yBAvCe,WAAW;wCAtDY;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;KAAE;6CAI7B;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;0CAOjE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;KAAE;4CAQlF;QACD,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;QAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;KACnB;kDAKgD;QAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE;wCAKxE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;KAAE"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ImageField } from '../fields/ImageField.js';
|
|
3
|
+
import { BodyField } from '../fields/BodyField.js';
|
|
4
|
+
import { TagList } from '../fields/TagList.js';
|
|
5
|
+
import { DateField } from '../fields/DateField.js';
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Sub-component primitives
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
function Root({ className, children }) {
|
|
10
|
+
return _jsx("article", { className: className, children: children });
|
|
11
|
+
}
|
|
12
|
+
function Cover({ entry, field = 'cover', className }) {
|
|
13
|
+
const data = entry.data;
|
|
14
|
+
const imageField = data[field] !== undefined || data[`${field}_media`] !== undefined ? field : undefined;
|
|
15
|
+
if (!imageField)
|
|
16
|
+
return null;
|
|
17
|
+
return _jsx(ImageField, { field: imageField, entry: entry, className: className, alt: "" });
|
|
18
|
+
}
|
|
19
|
+
function Header({ className, children }) {
|
|
20
|
+
return _jsx("header", { className: className, children: children });
|
|
21
|
+
}
|
|
22
|
+
function Body({ value, type = 'text', className, }) {
|
|
23
|
+
if (!value)
|
|
24
|
+
return null;
|
|
25
|
+
return _jsx(BodyField, { value: value, type: type, className: className });
|
|
26
|
+
}
|
|
27
|
+
function Tags({ tags, className, tagClassName }) {
|
|
28
|
+
if (!tags?.length)
|
|
29
|
+
return null;
|
|
30
|
+
return _jsx(TagList, { tags: tags, className: className, tagClassName: tagClassName });
|
|
31
|
+
}
|
|
32
|
+
function Meta({ className, children }) {
|
|
33
|
+
return _jsx("div", { className: className, children: children });
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Generic schema-driven detail / full-page view component.
|
|
37
|
+
*
|
|
38
|
+
* Renders: Cover → Header (title + date) → Body → Tags.
|
|
39
|
+
* Override via compound sub-components for surgical control.
|
|
40
|
+
*
|
|
41
|
+
* RSC-compatible — no `"use client"`.
|
|
42
|
+
*/
|
|
43
|
+
export function EntryDetail({ entry, collection, className, ...rest }) {
|
|
44
|
+
const data = entry.data;
|
|
45
|
+
const imageFieldName = Object.entries(collection.fields).find(([, f]) => f.type === 'image')?.[0];
|
|
46
|
+
const titleFieldName = Object.keys(collection.fields).find((k) => ['title', 'name', 'heading', 'label'].includes(k));
|
|
47
|
+
const bodyFieldName = Object.entries(collection.fields).find(([, f]) => f.type === 'rich-text' || f.type === 'text')?.[0];
|
|
48
|
+
const bodyFieldType = bodyFieldName ? collection.fields[bodyFieldName]?.type : undefined;
|
|
49
|
+
const tagsFieldName = Object.entries(collection.fields).find(([, f]) => f.type === 'multiselect' || f.type === 'list')?.[0];
|
|
50
|
+
const dateFieldName = Object.entries(collection.fields).find(([, f]) => f.type === 'date' || f.type === 'datetime')?.[0];
|
|
51
|
+
const title = titleFieldName ? data[titleFieldName] : undefined;
|
|
52
|
+
const bodyValue = bodyFieldName ? data[bodyFieldName] : undefined;
|
|
53
|
+
const tags = tagsFieldName ? data[tagsFieldName] : undefined;
|
|
54
|
+
const dateValue = dateFieldName ? data[dateFieldName] : undefined;
|
|
55
|
+
return (_jsxs("article", { className: className, ...rest, children: [imageFieldName && _jsx(Cover, { entry: entry, field: imageFieldName }), _jsxs(Header, { children: [title && _jsx("h1", { children: title }), dateValue && _jsx(DateField, { value: dateValue })] }), bodyValue && (_jsx(Body, { value: bodyValue, type: bodyFieldType === 'rich-text' ? 'rich-text' : 'text' })), tags && _jsx(Tags, { tags: tags })] }));
|
|
56
|
+
}
|
|
57
|
+
EntryDetail.Root = Root;
|
|
58
|
+
EntryDetail.Cover = Cover;
|
|
59
|
+
EntryDetail.Header = Header;
|
|
60
|
+
EntryDetail.Body = Body;
|
|
61
|
+
EntryDetail.Tags = Tags;
|
|
62
|
+
EntryDetail.Meta = Meta;
|
|
63
|
+
//# sourceMappingURL=EntryDetail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntryDetail.js","sourceRoot":"","sources":["../../src/compounds/EntryDetail.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/compounds/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/compounds/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAG1C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/** An expanded author entry with at least a name field. */
|
|
3
|
+
export interface ExpandedAuthor {
|
|
4
|
+
name?: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
label?: string;
|
|
7
|
+
slug?: string;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
export interface AuthorBylineProps {
|
|
11
|
+
/**
|
|
12
|
+
* Accept multiple shapes:
|
|
13
|
+
* - A single slug string
|
|
14
|
+
* - An array of slug strings
|
|
15
|
+
* - An array of expanded author objects (from `expand: ['authors']`)
|
|
16
|
+
*/
|
|
17
|
+
authors: string | string[] | ExpandedAuthor[];
|
|
18
|
+
className?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Renders a comma-separated author byline.
|
|
22
|
+
*
|
|
23
|
+
* RSC-compatible — no `"use client"`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function AuthorByline({ authors, className }: AuthorBylineProps): ReactNode;
|
|
26
|
+
//# sourceMappingURL=AuthorByline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthorByline.d.ts","sourceRoot":"","sources":["../../src/fields/AuthorByline.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,2DAA2D;AAC3D,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,cAAc,EAAE,CAAA;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAOD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,iBAAiB,GAAG,SAAS,CAMjF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
function getLabel(author) {
|
|
3
|
+
if (typeof author === 'string')
|
|
4
|
+
return author;
|
|
5
|
+
return String(author.name ?? author.title ?? author.label ?? author.slug ?? '');
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Renders a comma-separated author byline.
|
|
9
|
+
*
|
|
10
|
+
* RSC-compatible — no `"use client"`.
|
|
11
|
+
*/
|
|
12
|
+
export function AuthorByline({ authors, className }) {
|
|
13
|
+
const list = Array.isArray(authors) ? authors : [authors];
|
|
14
|
+
const labels = list.map(getLabel).filter(Boolean);
|
|
15
|
+
if (!labels.length)
|
|
16
|
+
return null;
|
|
17
|
+
return _jsx("span", { className: className, children: labels.join(', ') });
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=AuthorByline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthorByline.js","sourceRoot":"","sources":["../../src/fields/AuthorByline.tsx"],"names":[],"mappings":";AAsBA,SAAS,QAAQ,CAAC,MAA+B;IAC/C,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAA;IAC7C,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;AACjF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,OAAO,EAAE,SAAS,EAAqB;IACpE,MAAM,IAAI,GAAgC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;IACtF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACjD,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAE/B,OAAO,eAAM,SAAS,EAAE,SAAS,YAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAQ,CAAA;AAC/D,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export interface BodyFieldProps {
|
|
3
|
+
value: string;
|
|
4
|
+
/**
|
|
5
|
+
* - `'text'` → paragraphs separated by `\n\n`, single `\n` → `<br>`
|
|
6
|
+
* - `'rich-text'` → full Markdown rendered to sanitised HTML
|
|
7
|
+
*/
|
|
8
|
+
type?: 'text' | 'rich-text';
|
|
9
|
+
className?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Override the default renderer entirely.
|
|
12
|
+
* Receives the raw string value; return any ReactNode.
|
|
13
|
+
*/
|
|
14
|
+
render?: (text: string) => ReactNode;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Renders a body / content field from an Airdraft entry.
|
|
18
|
+
*
|
|
19
|
+
* RSC-compatible — no `"use client"`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function BodyField({ value, type, className, render }: BodyFieldProps): ReactNode;
|
|
22
|
+
//# sourceMappingURL=BodyField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BodyField.d.ts","sourceRoot":"","sources":["../../src/fields/BodyField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAA;CACrC;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,IAAa,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,cAAc,GAAG,SAAS,CA+BhG"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { parseMarkdown, parseText } from '@airdraft/content';
|
|
3
|
+
/**
|
|
4
|
+
* Renders a body / content field from an Airdraft entry.
|
|
5
|
+
*
|
|
6
|
+
* RSC-compatible — no `"use client"`.
|
|
7
|
+
*/
|
|
8
|
+
export function BodyField({ value, type = 'text', className, render }) {
|
|
9
|
+
if (!value)
|
|
10
|
+
return null;
|
|
11
|
+
if (render)
|
|
12
|
+
return render(value);
|
|
13
|
+
if (type === 'rich-text') {
|
|
14
|
+
const html = parseMarkdown(value);
|
|
15
|
+
return (_jsx("div", { className: className,
|
|
16
|
+
// DOMPurify sanitises the HTML in parseMarkdown before we use it here
|
|
17
|
+
dangerouslySetInnerHTML: { __html: html } }));
|
|
18
|
+
}
|
|
19
|
+
// Plain text — split into paragraphs
|
|
20
|
+
const paragraphs = parseText(value);
|
|
21
|
+
return (_jsx("div", { className: className, children: paragraphs.map((para, i) => (_jsx("p", { children: para.split('\n').map((line, j, arr) => (_jsxs("span", { children: [line, j < arr.length - 1 && _jsx("br", {})] }, j))) }, i))) }));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=BodyField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BodyField.js","sourceRoot":"","sources":["../../src/fields/BodyField.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAiB5D;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,EAAkB;IACnF,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;IAEhC,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAA;QACjC,OAAO,CACL,cACE,SAAS,EAAE,SAAS;YACpB,sEAAsE;YACtE,uBAAuB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GACzC,CACH,CAAA;IACH,CAAC;IAED,qCAAqC;IACrC,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;IACnC,OAAO,CACL,cAAK,SAAS,EAAE,SAAS,YACtB,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAC3B,sBACG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CACtC,2BACG,IAAI,EACJ,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,cAAM,KAFpB,CAAC,CAGL,CACR,CAAC,IANI,CAAC,CAOL,CACL,CAAC,GACE,CACP,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export interface DateFieldProps {
|
|
3
|
+
value: string | null | undefined;
|
|
4
|
+
/** Intl.DateTimeFormat options. Defaults to `{ dateStyle: 'medium' }`. */
|
|
5
|
+
format?: Intl.DateTimeFormatOptions;
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Renders a formatted date from an ISO string.
|
|
10
|
+
* Falls back silently on invalid dates.
|
|
11
|
+
*
|
|
12
|
+
* RSC-compatible — no `"use client"`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function DateField({ value, format, className }: DateFieldProps): ReactNode;
|
|
15
|
+
//# sourceMappingURL=DateField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateField.d.ts","sourceRoot":"","sources":["../../src/fields/DateField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IAChC,0EAA0E;IAC1E,MAAM,CAAC,EAAE,IAAI,CAAC,qBAAqB,CAAA;IACnC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,MAAgC,EAAE,SAAS,EAAE,EAAE,cAAc,GAAG,SAAS,CAW3G"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Renders a formatted date from an ISO string.
|
|
4
|
+
* Falls back silently on invalid dates.
|
|
5
|
+
*
|
|
6
|
+
* RSC-compatible — no `"use client"`.
|
|
7
|
+
*/
|
|
8
|
+
export function DateField({ value, format = { dateStyle: 'medium' }, className }) {
|
|
9
|
+
if (!value)
|
|
10
|
+
return null;
|
|
11
|
+
const date = new Date(value);
|
|
12
|
+
if (isNaN(date.getTime()))
|
|
13
|
+
return null;
|
|
14
|
+
const formatted = new Intl.DateTimeFormat('en-US', format).format(date);
|
|
15
|
+
return (_jsx("time", { dateTime: date.toISOString(), className: className, children: formatted }));
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=DateField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateField.js","sourceRoot":"","sources":["../../src/fields/DateField.tsx"],"names":[],"mappings":";AASA;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAkB;IAC9F,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAA;IAC5B,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,IAAI,CAAA;IAEtC,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACvE,OAAO,CACL,eAAM,QAAQ,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,SAAS,YACrD,SAAS,GACL,CACR,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { Entry } from '@airdraft/core';
|
|
3
|
+
export interface ImageFieldProps {
|
|
4
|
+
/** The field name in the entry's data (e.g. 'cover', 'thumbnail'). */
|
|
5
|
+
field: string;
|
|
6
|
+
/** The entry whose data is searched for the image. */
|
|
7
|
+
entry: Entry;
|
|
8
|
+
alt?: string;
|
|
9
|
+
className?: string;
|
|
10
|
+
/** Class applied to the rendered `<img>` when no children render prop is given. */
|
|
11
|
+
imgClassName?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Render prop — receives the resolved URL and renders a custom element.
|
|
14
|
+
* Use this to plug in `next/image`, `<picture>`, etc.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* <ImageField field="cover" entry={entry}>
|
|
18
|
+
* {(url) => <NextImage src={url} alt="cover" fill />}
|
|
19
|
+
* </ImageField>
|
|
20
|
+
*/
|
|
21
|
+
children?: (url: string) => ReactNode;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Renders an image resolved from an Airdraft entry field.
|
|
25
|
+
*
|
|
26
|
+
* Resolution chain: `{field}_media.url` → `{field}_url` → `/{field}` key.
|
|
27
|
+
* Returns `null` when no URL can be resolved.
|
|
28
|
+
*
|
|
29
|
+
* RSC-compatible — no `"use client"`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function ImageField({ field, entry, alt, className, imgClassName, children, }: ImageFieldProps): ReactNode;
|
|
32
|
+
//# sourceMappingURL=ImageField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImageField.d.ts","sourceRoot":"","sources":["../../src/fields/ImageField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAE3C,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAA;IACb,sDAAsD;IACtD,KAAK,EAAE,KAAK,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mFAAmF;IACnF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAA;CACtC;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,GAAQ,EACR,SAAS,EACT,YAAY,EACZ,QAAQ,GACT,EAAE,eAAe,GAAG,SAAS,CAU7B"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { resolveImageUrl } from '@airdraft/content';
|
|
3
|
+
/**
|
|
4
|
+
* Renders an image resolved from an Airdraft entry field.
|
|
5
|
+
*
|
|
6
|
+
* Resolution chain: `{field}_media.url` → `{field}_url` → `/{field}` key.
|
|
7
|
+
* Returns `null` when no URL can be resolved.
|
|
8
|
+
*
|
|
9
|
+
* RSC-compatible — no `"use client"`.
|
|
10
|
+
*/
|
|
11
|
+
export function ImageField({ field, entry, alt = '', className, imgClassName, children, }) {
|
|
12
|
+
const url = resolveImageUrl(field, entry.data);
|
|
13
|
+
if (!url)
|
|
14
|
+
return null;
|
|
15
|
+
if (children)
|
|
16
|
+
return children(url);
|
|
17
|
+
return (
|
|
18
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
19
|
+
_jsx("img", { src: url, alt: alt, className: imgClassName ?? className }));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=ImageField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImageField.js","sourceRoot":"","sources":["../../src/fields/ImageField.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAwBnD;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,GAAG,GAAG,EAAE,EACR,SAAS,EACT,YAAY,EACZ,QAAQ,GACQ;IAChB,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,IAA+B,CAAC,CAAA;IACzE,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IAErB,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAA;IAElC,OAAO;IACL,qDAAqD;IACrD,cAAK,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,YAAY,IAAI,SAAS,GAAI,CAClE,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export interface TagListProps {
|
|
3
|
+
tags: string[];
|
|
4
|
+
className?: string;
|
|
5
|
+
/** Class applied to each individual tag element. */
|
|
6
|
+
tagClassName?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Renders a list of string tags as inline `<span>` elements.
|
|
10
|
+
*
|
|
11
|
+
* RSC-compatible — no `"use client"`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function TagList({ tags, className, tagClassName }: TagListProps): ReactNode;
|
|
14
|
+
//# sourceMappingURL=TagList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TagList.d.ts","sourceRoot":"","sources":["../../src/fields/TagList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,YAAY,GAAG,SAAS,CAWlF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Renders a list of string tags as inline `<span>` elements.
|
|
4
|
+
*
|
|
5
|
+
* RSC-compatible — no `"use client"`.
|
|
6
|
+
*/
|
|
7
|
+
export function TagList({ tags, className, tagClassName }) {
|
|
8
|
+
if (!tags.length)
|
|
9
|
+
return null;
|
|
10
|
+
return (_jsx("div", { className: className, children: tags.map((tag) => (_jsx("span", { className: tagClassName, children: tag }, tag))) }));
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=TagList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TagList.js","sourceRoot":"","sources":["../../src/fields/TagList.tsx"],"names":[],"mappings":";AASA;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAgB;IACrE,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAC7B,OAAO,CACL,cAAK,SAAS,EAAE,SAAS,YACtB,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACjB,eAAgB,SAAS,EAAE,YAAY,YACpC,GAAG,IADK,GAAG,CAEP,CACR,CAAC,GACE,CACP,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { ImageField } from './ImageField.js';
|
|
2
|
+
export type { ImageFieldProps } from './ImageField.js';
|
|
3
|
+
export { BodyField } from './BodyField.js';
|
|
4
|
+
export type { BodyFieldProps } from './BodyField.js';
|
|
5
|
+
export { TagList } from './TagList.js';
|
|
6
|
+
export type { TagListProps } from './TagList.js';
|
|
7
|
+
export { AuthorByline } from './AuthorByline.js';
|
|
8
|
+
export type { AuthorBylineProps, ExpandedAuthor } from './AuthorByline.js';
|
|
9
|
+
export { DateField } from './DateField.js';
|
|
10
|
+
export type { DateFieldProps } from './DateField.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fields/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAE1E,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fields/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAG5C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAG1C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAGtC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGhD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAA;AAGjC,cAAc,sBAAsB,CAAA;AAGpC,cAAc,iBAAiB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,cAAc,mBAAmB,CAAA;AAEjC,4CAA4C;AAC5C,cAAc,sBAAsB,CAAA;AAEpC,uBAAuB;AACvB,cAAc,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { Entry } from '@airdraft/core';
|
|
3
|
+
export interface AirdraftImageProps {
|
|
4
|
+
/** The field name in the entry's data (e.g. 'cover', 'thumbnail'). */
|
|
5
|
+
field: string;
|
|
6
|
+
/** The entry whose data is searched for the image. */
|
|
7
|
+
entry: Entry;
|
|
8
|
+
alt?: string;
|
|
9
|
+
className?: string;
|
|
10
|
+
/** Passed through to next/image when dimensions are known. */
|
|
11
|
+
priority?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Next.js-aware image component backed by `next/image`.
|
|
15
|
+
*
|
|
16
|
+
* - Uses `{field}_media.width` + `height` when available → `<Image width height>`
|
|
17
|
+
* - Falls back to `<Image fill>` when dimensions are absent
|
|
18
|
+
* - Returns `null` when no URL can be resolved
|
|
19
|
+
*
|
|
20
|
+
* Place in `@airdraft/react-content/next` to keep it optional.
|
|
21
|
+
* RSC-compatible — no `"use client"`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function AirdraftImage({ field, entry, alt, className, priority }: AirdraftImageProps): ReactNode;
|
|
24
|
+
//# sourceMappingURL=AirdraftImage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AirdraftImage.d.ts","sourceRoot":"","sources":["../../src/next/AirdraftImage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAG3C,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAA;IACb,sDAAsD;IACtD,KAAK,EAAE,KAAK,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,kBAAkB,GAAG,SAAS,CA0B5G"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import Image from 'next/image';
|
|
3
|
+
import { resolveImageUrl, resolveImageDimensions } from '@airdraft/content';
|
|
4
|
+
/**
|
|
5
|
+
* Next.js-aware image component backed by `next/image`.
|
|
6
|
+
*
|
|
7
|
+
* - Uses `{field}_media.width` + `height` when available → `<Image width height>`
|
|
8
|
+
* - Falls back to `<Image fill>` when dimensions are absent
|
|
9
|
+
* - Returns `null` when no URL can be resolved
|
|
10
|
+
*
|
|
11
|
+
* Place in `@airdraft/react-content/next` to keep it optional.
|
|
12
|
+
* RSC-compatible — no `"use client"`.
|
|
13
|
+
*/
|
|
14
|
+
export function AirdraftImage({ field, entry, alt = '', className, priority }) {
|
|
15
|
+
const data = entry.data;
|
|
16
|
+
const src = resolveImageUrl(field, data);
|
|
17
|
+
if (!src)
|
|
18
|
+
return null;
|
|
19
|
+
const dims = resolveImageDimensions(field, data);
|
|
20
|
+
if (dims) {
|
|
21
|
+
return (_jsx(Image, { src: src, alt: alt, width: dims.width, height: dims.height, className: className, priority: priority }));
|
|
22
|
+
}
|
|
23
|
+
// No dimensions — use fill mode; caller must size the parent element
|
|
24
|
+
return (_jsx("div", { className: className, style: { position: 'relative' }, children: _jsx(Image, { src: src, alt: alt, fill: true, priority: priority }) }));
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=AirdraftImage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AirdraftImage.js","sourceRoot":"","sources":["../../src/next/AirdraftImage.tsx"],"names":[],"mappings":";AACA,OAAO,KAAK,MAAM,YAAY,CAAA;AAE9B,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAa3E;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,GAAG,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAsB;IAC/F,MAAM,IAAI,GAAG,KAAK,CAAC,IAA+B,CAAA;IAClD,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IACxC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IAErB,MAAM,IAAI,GAAG,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IAEhD,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,CACL,KAAC,KAAK,IACJ,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,MAAM,EAAE,IAAI,CAAC,MAAM,EACnB,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,GAClB,CACH,CAAA;IACH,CAAC;IAED,qEAAqE;IACrE,OAAO,CACL,cAAK,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,YACxD,KAAC,KAAK,IAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,QAAC,QAAQ,EAAE,QAAQ,GAAI,GAClD,CACP,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@airdraft/react-content",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Airdraft React components for rendering CMS content — field atoms, entry cards, and blog recipes",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./next": {
|
|
14
|
+
"import": "./dist/next/index.js",
|
|
15
|
+
"types": "./dist/next/index.d.ts"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": ["dist", "README.md", "CHANGELOG.md"],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"dev": "tsc --watch",
|
|
22
|
+
"clean": "rm -rf dist",
|
|
23
|
+
"typecheck": "tsc --noEmit",
|
|
24
|
+
"prepublishOnly": "npm run build",
|
|
25
|
+
"release": "standard-version",
|
|
26
|
+
"release:patch": "standard-version --release-as patch",
|
|
27
|
+
"release:minor": "standard-version --release-as minor",
|
|
28
|
+
"release:major": "standard-version --release-as major"
|
|
29
|
+
},
|
|
30
|
+
"publishConfig": { "access": "public" },
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"react": ">=18.0.0",
|
|
34
|
+
"next": ">=14.0.0"
|
|
35
|
+
},
|
|
36
|
+
"peerDependenciesMeta": {
|
|
37
|
+
"next": { "optional": true }
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/react": "^19.0.0",
|
|
41
|
+
"next": "^15.0.0",
|
|
42
|
+
"react": "^18.0.0",
|
|
43
|
+
"typescript": "^5.7.2"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@airdraft/content": "*",
|
|
47
|
+
"@airdraft/core": "*"
|
|
48
|
+
},
|
|
49
|
+
"engines": { "node": ">=18.0.0" }
|
|
50
|
+
}
|