@actuate-media/sections-react 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/LICENSE +21 -0
- package/dist/Sections.d.ts +38 -0
- package/dist/Sections.d.ts.map +1 -0
- package/dist/Sections.js +54 -0
- package/dist/Sections.js.map +1 -0
- package/dist/components/defaults.d.ts +19 -0
- package/dist/components/defaults.d.ts.map +1 -0
- package/dist/components/defaults.js +85 -0
- package/dist/components/defaults.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/primitives.d.ts +12 -0
- package/dist/primitives.d.ts.map +1 -0
- package/dist/primitives.js +18 -0
- package/dist/primitives.js.map +1 -0
- package/dist/registry.d.ts +40 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +62 -0
- package/dist/registry.js.map +1 -0
- package/dist/types.d.ts +82 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +19 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +60 -0
- package/dist/utils.js.map +1 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Actuate Media
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<Sections>` — render a document's canonical `PageSection[]` as a public
|
|
3
|
+
* page body, and `<PostHeader>` — render a post's header from its template
|
|
4
|
+
* config + the post's own field values.
|
|
5
|
+
*
|
|
6
|
+
* SSR-first: both are plain components safe to render in React Server
|
|
7
|
+
* Components. Each section is wrapped in a `<section>` carrying its background,
|
|
8
|
+
* padding, and optional anchor id; the inner content comes from the resolved
|
|
9
|
+
* renderer (see {@link getSectionRenderer}).
|
|
10
|
+
*/
|
|
11
|
+
import type { ReactNode } from 'react';
|
|
12
|
+
import { type PostHeaderConfig } from '@actuate-media/cms-core/page-sections';
|
|
13
|
+
import type { PostContext, PublicSection, RenderOptions, SectionRendererMap } from './types.js';
|
|
14
|
+
export interface SectionsProps {
|
|
15
|
+
/** The document's `data.sections` array. */
|
|
16
|
+
sections: PublicSection[];
|
|
17
|
+
/** Per-request post context (for post-oriented sections). */
|
|
18
|
+
ctx?: PostContext;
|
|
19
|
+
/**
|
|
20
|
+
* Per-render renderer overrides keyed by section type. Highest precedence —
|
|
21
|
+
* beats globally registered renderers and the built-in defaults.
|
|
22
|
+
*/
|
|
23
|
+
renderers?: SectionRendererMap;
|
|
24
|
+
/** Rendering options (e.g. an HTML sanitizer). */
|
|
25
|
+
options?: RenderOptions;
|
|
26
|
+
}
|
|
27
|
+
/** Render the visible sections of a document as a public page body. */
|
|
28
|
+
export declare function Sections({ sections, ctx, renderers, options }: SectionsProps): ReactNode;
|
|
29
|
+
export interface PostHeaderProps {
|
|
30
|
+
config: PostHeaderConfig;
|
|
31
|
+
ctx: PostContext;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Public post header, driven by the post type's template `header` config
|
|
35
|
+
* (layout + which fields to show) plus the post's own field values.
|
|
36
|
+
*/
|
|
37
|
+
export declare function PostHeader({ config, ctx }: PostHeaderProps): ReactNode;
|
|
38
|
+
//# sourceMappingURL=Sections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Sections.d.ts","sourceRoot":"","sources":["../src/Sections.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,uCAAuC,CAAA;AAEjG,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACb,aAAa,EAEb,kBAAkB,EACnB,MAAM,YAAY,CAAA;AAuBnB,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,QAAQ,EAAE,aAAa,EAAE,CAAA;IACzB,6DAA6D;IAC7D,GAAG,CAAC,EAAE,WAAW,CAAA;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,kBAAkB,CAAA;IAC9B,kDAAkD;IAClD,OAAO,CAAC,EAAE,aAAa,CAAA;CACxB;AAED,uEAAuE;AACvE,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,aAAa,GAAG,SAAS,CA2BxF;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,gBAAgB,CAAA;IACxB,GAAG,EAAE,WAAW,CAAA;CACjB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,eAAe,GAAG,SAAS,CAoEtE"}
|
package/dist/Sections.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { computeReadingTime } from '@actuate-media/cms-core/page-sections';
|
|
3
|
+
import { getSectionRenderer } from './registry.js';
|
|
4
|
+
import { backgroundClass, formatHeaderDate, paddingClass } from './utils.js';
|
|
5
|
+
const identity = (html) => html;
|
|
6
|
+
function resolveOptions(options) {
|
|
7
|
+
return { sanitizeHtml: options?.sanitizeHtml ?? identity };
|
|
8
|
+
}
|
|
9
|
+
/** Dev-only: warn at most once per unknown section type. */
|
|
10
|
+
const warnedTypes = new Set();
|
|
11
|
+
function warnUnknown(type) {
|
|
12
|
+
if (process.env.NODE_ENV === 'production')
|
|
13
|
+
return;
|
|
14
|
+
if (warnedTypes.has(type))
|
|
15
|
+
return;
|
|
16
|
+
warnedTypes.add(type);
|
|
17
|
+
// eslint-disable-next-line no-console
|
|
18
|
+
console.warn(`[@actuate-media/sections-react] No renderer for section type "${type}". ` +
|
|
19
|
+
'Register one with registerSectionRenderer() or pass it via the `renderers` prop. ' +
|
|
20
|
+
'Skipping this section.');
|
|
21
|
+
}
|
|
22
|
+
/** Render the visible sections of a document as a public page body. */
|
|
23
|
+
export function Sections({ sections, ctx, renderers, options }) {
|
|
24
|
+
const resolved = resolveOptions(options);
|
|
25
|
+
const visible = (Array.isArray(sections) ? sections : []).filter((s) => s?.visible !== false);
|
|
26
|
+
return (_jsx(_Fragment, { children: visible.map((section) => {
|
|
27
|
+
const renderer = getSectionRenderer(section.sectionType, renderers);
|
|
28
|
+
if (!renderer) {
|
|
29
|
+
warnUnknown(section.sectionType);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const s = section.settings ?? {};
|
|
33
|
+
const anchorId = typeof s.anchorId === 'string' && s.anchorId ? s.anchorId : undefined;
|
|
34
|
+
const cssClass = typeof s.cssClass === 'string' ? s.cssClass : '';
|
|
35
|
+
return (_jsx("section", { id: anchorId, className: `${backgroundClass(s)} ${paddingClass(s)} ${cssClass}`.trim(), children: renderer({ section, ctx, options: resolved }) }, section.id));
|
|
36
|
+
}) }));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Public post header, driven by the post type's template `header` config
|
|
40
|
+
* (layout + which fields to show) plus the post's own field values.
|
|
41
|
+
*/
|
|
42
|
+
export function PostHeader({ config, ctx }) {
|
|
43
|
+
const title = ctx.title || 'Untitled';
|
|
44
|
+
const date = config.showDate ? formatHeaderDate(ctx.publishDate) : '';
|
|
45
|
+
const overlay = config.layout === 'overlay' && config.showFeaturedImage && !!ctx.featuredImageUrl;
|
|
46
|
+
const centered = config.layout === 'centered';
|
|
47
|
+
const align = centered ? 'mx-auto items-center text-center' : 'text-left';
|
|
48
|
+
const meta = (_jsxs("div", { className: `mt-4 flex flex-wrap gap-x-3 gap-y-1 text-sm ${centered ? 'justify-center' : ''} ${overlay ? 'text-white/80' : 'text-zinc-500'}`, children: [config.showCategory && ctx.category && (_jsx("span", { className: "font-medium text-violet-500", children: ctx.category })), config.showAuthor && ctx.author?.name && _jsx("span", { children: ctx.author.name }), date && _jsx("span", { children: date }), config.showReadingTime && _jsxs("span", { children: [computeReadingTime(ctx.body), " min read"] })] }));
|
|
49
|
+
if (overlay) {
|
|
50
|
+
return (_jsxs("header", { className: "relative", children: [_jsx("img", { src: ctx.featuredImageUrl, alt: "", className: "h-[360px] w-full object-cover sm:h-[440px]" }), _jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/70 to-black/10", "aria-hidden": true }), _jsx("div", { className: "absolute inset-x-0 bottom-0 px-6 pb-10", children: _jsxs("div", { className: `mx-auto flex max-w-3xl flex-col ${align}`, children: [_jsx("h1", { className: "text-3xl font-bold tracking-tight text-white sm:text-5xl", children: title }), config.showExcerpt && ctx.excerpt && (_jsx("p", { className: "mt-3 max-w-2xl text-lg text-white/90", children: ctx.excerpt })), meta] }) })] }));
|
|
51
|
+
}
|
|
52
|
+
return (_jsxs("header", { className: "border-b border-zinc-100 bg-zinc-50 py-16", children: [_jsxs("div", { className: `mx-auto flex max-w-3xl flex-col px-6 ${align}`, children: [_jsx("h1", { className: "text-4xl font-bold tracking-tight text-zinc-900 sm:text-5xl", children: title }), config.showExcerpt && ctx.excerpt && (_jsx("p", { className: `mt-4 max-w-2xl text-lg text-zinc-600 ${centered ? 'mx-auto' : ''}`, children: ctx.excerpt })), meta] }), config.showFeaturedImage && ctx.featuredImageUrl && (_jsx("div", { className: "mx-auto mt-8 max-w-4xl px-6", children: _jsx("img", { src: ctx.featuredImageUrl, alt: title, className: "aspect-video w-full rounded-xl object-cover shadow-sm" }) }))] }));
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=Sections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Sections.js","sourceRoot":"","sources":["../src/Sections.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { SectionRenderer, SectionRendererMap } from '../types.js';
|
|
2
|
+
export declare const HeroSection: SectionRenderer;
|
|
3
|
+
export declare const TextSection: SectionRenderer;
|
|
4
|
+
export declare const FeatureSection: SectionRenderer;
|
|
5
|
+
export declare const StatsSection: SectionRenderer;
|
|
6
|
+
export declare const CtaSection: SectionRenderer;
|
|
7
|
+
export declare const ArticleBodySection: SectionRenderer;
|
|
8
|
+
export declare const QuoteSection: SectionRenderer;
|
|
9
|
+
export declare const AuthorBioSection: SectionRenderer;
|
|
10
|
+
export declare const RelatedPostsSection: SectionRenderer;
|
|
11
|
+
export declare const GallerySection: SectionRenderer;
|
|
12
|
+
/**
|
|
13
|
+
* The built-in renderer map. Keys are the canonical `sectionType` ids from
|
|
14
|
+
* `@actuate-media/cms-core/page-sections`. A drift guard (see registry tests)
|
|
15
|
+
* keeps this in lockstep with the cms-core registry so no section type can
|
|
16
|
+
* exist without a renderer.
|
|
17
|
+
*/
|
|
18
|
+
export declare const DEFAULT_SECTION_RENDERERS: SectionRendererMap;
|
|
19
|
+
//# sourceMappingURL=defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/components/defaults.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAwB,MAAM,aAAa,CAAA;AAI5F,eAAO,MAAM,WAAW,EAAE,eA4BzB,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,eAWzB,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,eAgC5B,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,eAuB1B,CAAA;AAED,eAAO,MAAM,UAAU,EAAE,eAkBxB,CAAA;AAED,eAAO,MAAM,kBAAkB,EAAE,eAqBhC,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,eAe1B,CAAA;AAED,eAAO,MAAM,gBAAgB,EAAE,eAiC9B,CAAA;AAED,eAAO,MAAM,mBAAmB,EAAE,eA2BjC,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,eA2B5B,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,EAAE,kBAWvC,CAAA"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from '../primitives.js';
|
|
3
|
+
import { bool, isDark, rows, str } from '../utils.js';
|
|
4
|
+
export const HeroSection = ({ section }) => {
|
|
5
|
+
const c = section.content;
|
|
6
|
+
const dark = isDark(section.settings);
|
|
7
|
+
return (_jsxs("div", { className: "mx-auto max-w-3xl px-6 text-center", children: [str(c, 'eyebrow') && (_jsx("p", { className: "mb-3 text-sm font-medium tracking-wide uppercase opacity-80", children: str(c, 'eyebrow') })), _jsx("h1", { className: "text-4xl font-bold tracking-tight sm:text-5xl", children: str(c, 'heading') }), str(c, 'body') && (_jsx("p", { className: "mx-auto mt-4 max-w-2xl text-lg opacity-90", children: str(c, 'body') })), _jsxs("div", { className: "mt-8 flex flex-wrap items-center justify-center gap-3", children: [_jsx(Button, { label: str(c, 'primaryButtonLabel'), href: str(c, 'primaryButtonUrl'), tone: dark ? 'onDark' : 'primary' }), _jsx(Button, { label: str(c, 'secondaryButtonLabel'), href: str(c, 'secondaryButtonUrl'), tone: "ghost" })] })] }));
|
|
8
|
+
};
|
|
9
|
+
export const TextSection = ({ section }) => {
|
|
10
|
+
const c = section.content;
|
|
11
|
+
const align = str(c, 'alignment', 'center') === 'left' ? 'text-left' : 'mx-auto text-center';
|
|
12
|
+
return (_jsxs("div", { className: `max-w-3xl px-6 ${align}`, children: [_jsx("h2", { className: "text-3xl font-bold tracking-tight", children: str(c, 'heading') }), str(c, 'body') && (_jsx("p", { className: "mt-4 text-lg whitespace-pre-line opacity-80", children: str(c, 'body') }))] }));
|
|
13
|
+
};
|
|
14
|
+
export const FeatureSection = ({ section }) => {
|
|
15
|
+
const c = section.content;
|
|
16
|
+
const left = str(c, 'imagePosition', 'right') === 'left';
|
|
17
|
+
const img = str(c, 'imageUrl');
|
|
18
|
+
return (_jsxs("div", { className: "mx-auto grid max-w-5xl items-center gap-10 px-6 md:grid-cols-2", children: [_jsxs("div", { className: left ? 'md:order-2' : '', children: [str(c, 'label') && (_jsx("p", { className: "mb-2 text-sm font-medium tracking-wide text-violet-600 uppercase", children: str(c, 'label') })), _jsx("h2", { className: "text-3xl font-bold tracking-tight", children: str(c, 'heading') }), str(c, 'body') && _jsx("p", { className: "mt-3 text-lg opacity-80", children: str(c, 'body') }), _jsx("div", { className: "mt-5", children: _jsx(Button, { label: str(c, 'buttonLabel'), href: str(c, 'buttonUrl') }) })] }), _jsx("div", { className: left ? 'md:order-1' : '', children: img ? (
|
|
19
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
20
|
+
_jsx("img", { src: img, alt: str(c, 'imageAlt'), className: "w-full rounded-xl object-cover shadow-sm" })) : (_jsx("div", { className: "aspect-video w-full rounded-xl bg-zinc-100", "aria-hidden": true })) })] }));
|
|
21
|
+
};
|
|
22
|
+
export const StatsSection = ({ section }) => {
|
|
23
|
+
const c = section.content;
|
|
24
|
+
return (_jsxs("div", { className: "mx-auto max-w-5xl px-6 text-center", children: [str(c, 'heading') && (_jsx("h2", { className: "text-3xl font-bold tracking-tight", children: str(c, 'heading') })), str(c, 'body') && (_jsx("p", { className: "mx-auto mt-3 max-w-2xl text-lg opacity-80", children: str(c, 'body') })), _jsx("dl", { className: "mt-10 grid grid-cols-1 gap-8 sm:grid-cols-3", children: rows(c, 'stats').map((row, i) => (_jsxs("div", { children: [_jsx("dt", { className: "text-4xl font-bold text-violet-600", children: str(row, 'value') }), _jsx("dd", { className: "mt-1 text-sm font-medium opacity-70", children: str(row, 'label') }), str(row, 'description') && (_jsx("dd", { className: "mt-1 text-xs opacity-60", children: str(row, 'description') }))] }, i))) })] }));
|
|
25
|
+
};
|
|
26
|
+
export const CtaSection = ({ section }) => {
|
|
27
|
+
const c = section.content;
|
|
28
|
+
const dark = isDark(section.settings);
|
|
29
|
+
return (_jsxs("div", { className: "mx-auto max-w-3xl px-6 text-center", children: [_jsx("h2", { className: "text-3xl font-bold tracking-tight", children: str(c, 'heading') }), str(c, 'body') && (_jsx("p", { className: "mx-auto mt-3 max-w-xl text-lg opacity-90", children: str(c, 'body') })), _jsx("div", { className: "mt-6", children: _jsx(Button, { label: str(c, 'buttonLabel'), href: str(c, 'buttonUrl'), tone: dark ? 'onDark' : 'primary' }) })] }));
|
|
30
|
+
};
|
|
31
|
+
export const ArticleBodySection = ({ section, ctx, options, }) => {
|
|
32
|
+
const c = section.content;
|
|
33
|
+
const source = str(c, 'source', 'field');
|
|
34
|
+
const rawHtml = source === 'override' ? str(c, 'body') : (ctx?.body ?? '');
|
|
35
|
+
const width = str(c, 'width', 'normal') === 'wide' ? 'max-w-4xl' : 'max-w-2xl';
|
|
36
|
+
if (!rawHtml) {
|
|
37
|
+
return _jsx("div", { className: `mx-auto ${width} px-6 text-zinc-400 italic`, children: "No body content yet." });
|
|
38
|
+
}
|
|
39
|
+
// Author-supplied HTML. Actuate sanitizes on write; `options.sanitizeHtml`
|
|
40
|
+
// (default identity) lets consumers add defense-in-depth — see RenderOptions.
|
|
41
|
+
const html = options.sanitizeHtml(rawHtml);
|
|
42
|
+
return (_jsx("div", { className: `prose prose-zinc mx-auto ${width} px-6`, dangerouslySetInnerHTML: { __html: html } }));
|
|
43
|
+
};
|
|
44
|
+
export const QuoteSection = ({ section }) => {
|
|
45
|
+
const c = section.content;
|
|
46
|
+
return (_jsxs("figure", { className: "mx-auto max-w-3xl px-6 text-center", children: [_jsxs("blockquote", { className: "text-2xl font-medium text-zinc-900 sm:text-3xl", children: ["\u201C", str(c, 'quote'), "\u201D"] }), (str(c, 'attribution') || str(c, 'role')) && (_jsxs("figcaption", { className: "mt-4 text-sm text-zinc-500", children: [str(c, 'attribution'), str(c, 'role') && _jsxs("span", { className: "opacity-70", children: [" \u2014 ", str(c, 'role')] })] }))] }));
|
|
47
|
+
};
|
|
48
|
+
export const AuthorBioSection = ({ section, ctx, }) => {
|
|
49
|
+
const c = section.content;
|
|
50
|
+
const author = ctx?.author;
|
|
51
|
+
return (_jsxs("div", { className: "mx-auto max-w-3xl px-6", children: [str(c, 'heading') && (_jsx("h2", { className: "mb-4 text-sm font-semibold tracking-wide text-zinc-500 uppercase", children: str(c, 'heading') })), _jsxs("div", { className: "flex items-center gap-4", children: [bool(c, 'showAvatar', true) && (_jsx("div", { className: "h-14 w-14 shrink-0 overflow-hidden rounded-full bg-zinc-200", children: author?.avatarUrl && (
|
|
52
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
53
|
+
_jsx("img", { src: author.avatarUrl, alt: author.name ?? '', className: "h-full w-full object-cover" })) })), _jsxs("div", { children: [_jsx("p", { className: "font-medium text-zinc-900", children: author?.name ?? 'Staff Writer' }), author?.bio && _jsx("p", { className: "mt-1 text-sm text-zinc-600", children: author.bio })] })] })] }));
|
|
54
|
+
};
|
|
55
|
+
export const RelatedPostsSection = ({ section, ctx, }) => {
|
|
56
|
+
const c = section.content;
|
|
57
|
+
const related = ctx?.relatedPosts ?? [];
|
|
58
|
+
const placeholders = related.length ? related : [null, null, null];
|
|
59
|
+
return (_jsxs("div", { className: "mx-auto max-w-5xl px-6", children: [str(c, 'heading') && (_jsx("h2", { className: "mb-6 text-2xl font-bold tracking-tight", children: str(c, 'heading') })), _jsx("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-3", children: placeholders.map((p, i) => (_jsxs("a", { href: p?.url ?? '#', className: "block rounded-xl border border-zinc-200 p-5 transition-colors hover:border-violet-300 hover:bg-zinc-50", children: [_jsx("p", { className: "font-medium text-zinc-900", children: p?.title ?? 'Related post' }), p?.excerpt && _jsx("p", { className: "mt-2 text-sm text-zinc-600", children: p.excerpt })] }, i))) })] }));
|
|
60
|
+
};
|
|
61
|
+
export const GallerySection = ({ section }) => {
|
|
62
|
+
const c = section.content;
|
|
63
|
+
const cols = str(c, 'columns', '3');
|
|
64
|
+
const colClass = cols === '2' ? 'sm:grid-cols-2' : cols === '4' ? 'sm:grid-cols-4' : 'sm:grid-cols-3';
|
|
65
|
+
return (_jsxs("div", { className: "mx-auto max-w-5xl px-6", children: [str(c, 'heading') && (_jsx("h2", { className: "mb-6 text-2xl font-bold tracking-tight", children: str(c, 'heading') })), _jsx("div", { className: `grid grid-cols-1 gap-4 ${colClass}`, children: rows(c, 'images').map((img, i) => (_jsxs("figure", { children: [_jsx("img", { src: str(img, 'url'), alt: str(img, 'alt'), className: "aspect-square w-full rounded-lg object-cover" }), str(img, 'caption') && (_jsx("figcaption", { className: "mt-1 text-xs text-zinc-500", children: str(img, 'caption') }))] }, i))) })] }));
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* The built-in renderer map. Keys are the canonical `sectionType` ids from
|
|
69
|
+
* `@actuate-media/cms-core/page-sections`. A drift guard (see registry tests)
|
|
70
|
+
* keeps this in lockstep with the cms-core registry so no section type can
|
|
71
|
+
* exist without a renderer.
|
|
72
|
+
*/
|
|
73
|
+
export const DEFAULT_SECTION_RENDERERS = {
|
|
74
|
+
hero: HeroSection,
|
|
75
|
+
text: TextSection,
|
|
76
|
+
feature: FeatureSection,
|
|
77
|
+
stats: StatsSection,
|
|
78
|
+
cta: CtaSection,
|
|
79
|
+
'article-body': ArticleBodySection,
|
|
80
|
+
quote: QuoteSection,
|
|
81
|
+
'author-bio': AuthorBioSection,
|
|
82
|
+
'related-posts': RelatedPostsSection,
|
|
83
|
+
gallery: GallerySection,
|
|
84
|
+
};
|
|
85
|
+
//# sourceMappingURL=defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/components/defaults.tsx"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@actuate-media/sections-react` — the public renderer for Actuate's
|
|
3
|
+
* canonical page-content contract (ADR 0001): a document's ordered
|
|
4
|
+
* `PageSection[]` (`data.sections`).
|
|
5
|
+
*
|
|
6
|
+
* Quick start (a Next.js Server Component):
|
|
7
|
+
*
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { Sections } from '@actuate-media/sections-react'
|
|
10
|
+
*
|
|
11
|
+
* export default async function Page() {
|
|
12
|
+
* const doc = await client.resolve('/about')
|
|
13
|
+
* return <Sections sections={doc?.data?.sections ?? []} />
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* Override a built-in section type for a custom design — either per render:
|
|
18
|
+
*
|
|
19
|
+
* ```tsx
|
|
20
|
+
* <Sections sections={sections} renderers={{ hero: MyHero }} />
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* …or globally at app startup:
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { registerSectionRenderer } from '@actuate-media/sections-react'
|
|
27
|
+
* registerSectionRenderer('hero', MyHero)
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export { Sections, PostHeader } from './Sections.js';
|
|
31
|
+
export type { SectionsProps, PostHeaderProps } from './Sections.js';
|
|
32
|
+
export { registerSectionRenderer, registerSectionRenderers, unregisterSectionRenderer, resetSectionRenderers, getSectionRenderer, registeredSectionTypes, DEFAULT_SECTION_RENDERERS, } from './registry.js';
|
|
33
|
+
export { HeroSection, TextSection, FeatureSection, StatsSection, CtaSection, ArticleBodySection, QuoteSection, AuthorBioSection, RelatedPostsSection, GallerySection, } from './components/defaults.js';
|
|
34
|
+
export { Button } from './primitives.js';
|
|
35
|
+
export type { PublicSection, PostContext, RenderOptions, ResolvedRenderOptions, SectionRenderer, SectionRendererProps, SectionRendererMap, } from './types.js';
|
|
36
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AACpD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAEnE,OAAO,EACL,uBAAuB,EACvB,wBAAwB,EACxB,yBAAyB,EACzB,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,eAAe,CAAA;AAEtB,OAAO,EACL,WAAW,EACX,WAAW,EACX,cAAc,EACd,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,GACf,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAExC,YAAY,EACV,aAAa,EACb,WAAW,EACX,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,YAAY,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@actuate-media/sections-react` — the public renderer for Actuate's
|
|
3
|
+
* canonical page-content contract (ADR 0001): a document's ordered
|
|
4
|
+
* `PageSection[]` (`data.sections`).
|
|
5
|
+
*
|
|
6
|
+
* Quick start (a Next.js Server Component):
|
|
7
|
+
*
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { Sections } from '@actuate-media/sections-react'
|
|
10
|
+
*
|
|
11
|
+
* export default async function Page() {
|
|
12
|
+
* const doc = await client.resolve('/about')
|
|
13
|
+
* return <Sections sections={doc?.data?.sections ?? []} />
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* Override a built-in section type for a custom design — either per render:
|
|
18
|
+
*
|
|
19
|
+
* ```tsx
|
|
20
|
+
* <Sections sections={sections} renderers={{ hero: MyHero }} />
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* …or globally at app startup:
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { registerSectionRenderer } from '@actuate-media/sections-react'
|
|
27
|
+
* registerSectionRenderer('hero', MyHero)
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export { Sections, PostHeader } from './Sections.js';
|
|
31
|
+
export { registerSectionRenderer, registerSectionRenderers, unregisterSectionRenderer, resetSectionRenderers, getSectionRenderer, registeredSectionTypes, DEFAULT_SECTION_RENDERERS, } from './registry.js';
|
|
32
|
+
export { HeroSection, TextSection, FeatureSection, StatsSection, CtaSection, ArticleBodySection, QuoteSection, AuthorBioSection, RelatedPostsSection, GallerySection, } from './components/defaults.js';
|
|
33
|
+
export { Button } from './primitives.js';
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAGpD,OAAO,EACL,uBAAuB,EACvB,wBAAwB,EACxB,yBAAyB,EACzB,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,eAAe,CAAA;AAEtB,OAAO,EACL,WAAW,EACX,WAAW,EACX,cAAc,EACd,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,GACf,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A link-styled button used by the hero/feature/cta default renderers.
|
|
4
|
+
* Renders nothing when there is no label, so optional secondary buttons
|
|
5
|
+
* collapse cleanly. Empty hrefs fall back to `#`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function Button({ label, href, tone, }: {
|
|
8
|
+
label: string;
|
|
9
|
+
href: string;
|
|
10
|
+
tone?: 'primary' | 'onDark' | 'ghost';
|
|
11
|
+
}): ReactNode;
|
|
12
|
+
//# sourceMappingURL=primitives.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../src/primitives.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,EACrB,KAAK,EACL,IAAI,EACJ,IAAgB,GACjB,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAA;CACtC,GAAG,SAAS,CAeZ"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* A link-styled button used by the hero/feature/cta default renderers.
|
|
4
|
+
* Renders nothing when there is no label, so optional secondary buttons
|
|
5
|
+
* collapse cleanly. Empty hrefs fall back to `#`.
|
|
6
|
+
*/
|
|
7
|
+
export function Button({ label, href, tone = 'primary', }) {
|
|
8
|
+
if (!label)
|
|
9
|
+
return null;
|
|
10
|
+
const base = 'inline-flex items-center justify-center rounded-lg px-5 py-2.5 text-sm font-medium transition-colors';
|
|
11
|
+
const toneClass = tone === 'onDark'
|
|
12
|
+
? 'bg-white text-violet-700 hover:bg-violet-50'
|
|
13
|
+
: tone === 'ghost'
|
|
14
|
+
? 'border border-zinc-300 text-zinc-700 hover:bg-zinc-50'
|
|
15
|
+
: 'bg-violet-600 text-white hover:bg-violet-700';
|
|
16
|
+
return (_jsx("a", { href: href || '#', className: `${base} ${toneClass}`, children: label }));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=primitives.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../src/primitives.tsx"],"names":[],"mappings":";AAEA;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,EACrB,KAAK,EACL,IAAI,EACJ,IAAI,GAAG,SAAS,GAKjB;IACC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,MAAM,IAAI,GACR,sGAAsG,CAAA;IACxG,MAAM,SAAS,GACb,IAAI,KAAK,QAAQ;QACf,CAAC,CAAC,6CAA6C;QAC/C,CAAC,CAAC,IAAI,KAAK,OAAO;YAChB,CAAC,CAAC,uDAAuD;YACzD,CAAC,CAAC,8CAA8C,CAAA;IACtD,OAAO,CACL,YAAG,IAAI,EAAE,IAAI,IAAI,GAAG,EAAE,SAAS,EAAE,GAAG,IAAI,IAAI,SAAS,EAAE,YACpD,KAAK,GACJ,CACL,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consumer-controlled section renderer registry (ADR 0001).
|
|
3
|
+
*
|
|
4
|
+
* Resolution precedence when `<Sections>` renders a section:
|
|
5
|
+
* 1. a renderer passed via the `renderers` prop (per-render override)
|
|
6
|
+
* 2. a globally registered renderer (`registerSectionRenderer`)
|
|
7
|
+
* 3. the built-in default renderer
|
|
8
|
+
* 4. the fallback (renders nothing; warns once in development)
|
|
9
|
+
*
|
|
10
|
+
* The global registry is a module-level map intended to be populated ONCE at
|
|
11
|
+
* application start (an import side-effect), mirroring how cms-core's runtime
|
|
12
|
+
* config is set once per process. For per-request or test-scoped overrides,
|
|
13
|
+
* prefer the `renderers` prop, which never mutates global state.
|
|
14
|
+
*/
|
|
15
|
+
import { DEFAULT_SECTION_RENDERERS } from './components/defaults.js';
|
|
16
|
+
import type { SectionRenderer, SectionRendererMap } from './types.js';
|
|
17
|
+
/**
|
|
18
|
+
* Register (or replace) the renderer for a section type, application-wide.
|
|
19
|
+
* Call at module top-level during app startup. Returns nothing.
|
|
20
|
+
*/
|
|
21
|
+
export declare function registerSectionRenderer(type: string, renderer: SectionRenderer): void;
|
|
22
|
+
/** Register many renderers at once. */
|
|
23
|
+
export declare function registerSectionRenderers(map: SectionRendererMap): void;
|
|
24
|
+
/** Remove a global override (falls back to the built-in default, if any). */
|
|
25
|
+
export declare function unregisterSectionRenderer(type: string): void;
|
|
26
|
+
/** Clear ALL global overrides. Primarily for tests. */
|
|
27
|
+
export declare function resetSectionRenderers(): void;
|
|
28
|
+
/**
|
|
29
|
+
* Resolve the renderer for a section type, honoring (in order) an explicit
|
|
30
|
+
* per-render map, the global overrides, then the built-in defaults. Returns
|
|
31
|
+
* `undefined` for unknown types so the caller can apply its fallback.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getSectionRenderer(type: string, perRender?: SectionRendererMap): SectionRenderer | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* The section-type ids that currently have a renderer (defaults + overrides).
|
|
36
|
+
* Used by the registry-drift guard to compare against the cms-core registry.
|
|
37
|
+
*/
|
|
38
|
+
export declare function registeredSectionTypes(): string[];
|
|
39
|
+
export { DEFAULT_SECTION_RENDERERS };
|
|
40
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAA;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAKrE;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI,CAQrF;AAED,uCAAuC;AACvC,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI,CAItE;AAED,6EAA6E;AAC7E,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE5D;AAED,uDAAuD;AACvD,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,kBAAkB,GAC7B,eAAe,GAAG,SAAS,CAE7B;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAIjD;AAED,OAAO,EAAE,yBAAyB,EAAE,CAAA"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consumer-controlled section renderer registry (ADR 0001).
|
|
3
|
+
*
|
|
4
|
+
* Resolution precedence when `<Sections>` renders a section:
|
|
5
|
+
* 1. a renderer passed via the `renderers` prop (per-render override)
|
|
6
|
+
* 2. a globally registered renderer (`registerSectionRenderer`)
|
|
7
|
+
* 3. the built-in default renderer
|
|
8
|
+
* 4. the fallback (renders nothing; warns once in development)
|
|
9
|
+
*
|
|
10
|
+
* The global registry is a module-level map intended to be populated ONCE at
|
|
11
|
+
* application start (an import side-effect), mirroring how cms-core's runtime
|
|
12
|
+
* config is set once per process. For per-request or test-scoped overrides,
|
|
13
|
+
* prefer the `renderers` prop, which never mutates global state.
|
|
14
|
+
*/
|
|
15
|
+
import { DEFAULT_SECTION_RENDERERS } from './components/defaults.js';
|
|
16
|
+
/** App-wide overrides registered via {@link registerSectionRenderer}. */
|
|
17
|
+
const overrides = {};
|
|
18
|
+
/**
|
|
19
|
+
* Register (or replace) the renderer for a section type, application-wide.
|
|
20
|
+
* Call at module top-level during app startup. Returns nothing.
|
|
21
|
+
*/
|
|
22
|
+
export function registerSectionRenderer(type, renderer) {
|
|
23
|
+
if (!type || typeof type !== 'string') {
|
|
24
|
+
throw new Error('registerSectionRenderer: `type` must be a non-empty string');
|
|
25
|
+
}
|
|
26
|
+
if (typeof renderer !== 'function') {
|
|
27
|
+
throw new Error(`registerSectionRenderer("${type}"): renderer must be a function`);
|
|
28
|
+
}
|
|
29
|
+
overrides[type] = renderer;
|
|
30
|
+
}
|
|
31
|
+
/** Register many renderers at once. */
|
|
32
|
+
export function registerSectionRenderers(map) {
|
|
33
|
+
for (const [type, renderer] of Object.entries(map)) {
|
|
34
|
+
registerSectionRenderer(type, renderer);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** Remove a global override (falls back to the built-in default, if any). */
|
|
38
|
+
export function unregisterSectionRenderer(type) {
|
|
39
|
+
delete overrides[type];
|
|
40
|
+
}
|
|
41
|
+
/** Clear ALL global overrides. Primarily for tests. */
|
|
42
|
+
export function resetSectionRenderers() {
|
|
43
|
+
for (const key of Object.keys(overrides))
|
|
44
|
+
delete overrides[key];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Resolve the renderer for a section type, honoring (in order) an explicit
|
|
48
|
+
* per-render map, the global overrides, then the built-in defaults. Returns
|
|
49
|
+
* `undefined` for unknown types so the caller can apply its fallback.
|
|
50
|
+
*/
|
|
51
|
+
export function getSectionRenderer(type, perRender) {
|
|
52
|
+
return perRender?.[type] ?? overrides[type] ?? DEFAULT_SECTION_RENDERERS[type];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The section-type ids that currently have a renderer (defaults + overrides).
|
|
56
|
+
* Used by the registry-drift guard to compare against the cms-core registry.
|
|
57
|
+
*/
|
|
58
|
+
export function registeredSectionTypes() {
|
|
59
|
+
return Array.from(new Set([...Object.keys(DEFAULT_SECTION_RENDERERS), ...Object.keys(overrides)])).sort();
|
|
60
|
+
}
|
|
61
|
+
export { DEFAULT_SECTION_RENDERERS };
|
|
62
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAA;AAGpE,yEAAyE;AACzE,MAAM,SAAS,GAAuB,EAAE,CAAA;AAExC;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY,EAAE,QAAyB;IAC7E,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAA;IAC/E,CAAC;IACD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,iCAAiC,CAAC,CAAA;IACpF,CAAC;IACD,SAAS,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAA;AAC5B,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,wBAAwB,CAAC,GAAuB;IAC9D,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACnD,uBAAuB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;IACzC,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,yBAAyB,CAAC,IAAY;IACpD,OAAO,SAAS,CAAC,IAAI,CAAC,CAAA;AACxB,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,qBAAqB;IACnC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC,GAAG,CAAC,CAAA;AACjE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,SAA8B;IAE9B,OAAO,SAAS,EAAE,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,yBAAyB,CAAC,IAAI,CAAC,CAAA;AAChF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,KAAK,CAAC,IAAI,CACf,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAChF,CAAC,IAAI,EAAE,CAAA;AACV,CAAC;AAED,OAAO,EAAE,yBAAyB,EAAE,CAAA"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public types for the Actuate section renderer.
|
|
3
|
+
*
|
|
4
|
+
* A page/post's renderable content is the ordered `PageSection[]` stored on a
|
|
5
|
+
* document's `data.sections` JSON (the canonical content contract — see
|
|
6
|
+
* ADR 0001). This package turns that array into server-rendered React.
|
|
7
|
+
*
|
|
8
|
+
* The wire shape here is intentionally permissive (`content`/`settings` are
|
|
9
|
+
* open records) because it comes off the network as JSON. The authoritative
|
|
10
|
+
* field schemas live in `@actuate-media/cms-core/page-sections`.
|
|
11
|
+
*/
|
|
12
|
+
import type { ReactNode } from 'react';
|
|
13
|
+
/** A single section as delivered by the CMS (`data.sections[]`). */
|
|
14
|
+
export interface PublicSection {
|
|
15
|
+
id: string;
|
|
16
|
+
/** Keys into the section registry; unknown types render via the fallback. */
|
|
17
|
+
sectionType: string;
|
|
18
|
+
name?: string;
|
|
19
|
+
/** Hidden sections are skipped by `<Sections>`. Absent means visible. */
|
|
20
|
+
visible?: boolean;
|
|
21
|
+
content?: Record<string, unknown>;
|
|
22
|
+
settings?: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Per-request context for post-oriented sections (article body, author bio,
|
|
26
|
+
* related posts) and the post header. Supplied by the consumer's data layer;
|
|
27
|
+
* never trusted for HTML unless sanitized (see {@link RenderOptions}).
|
|
28
|
+
*/
|
|
29
|
+
export interface PostContext {
|
|
30
|
+
title?: string;
|
|
31
|
+
excerpt?: string;
|
|
32
|
+
/** Post body HTML — used by the `article-body` section in `source: 'field'` mode. */
|
|
33
|
+
body?: string;
|
|
34
|
+
featuredImageUrl?: string;
|
|
35
|
+
publishDate?: string | null;
|
|
36
|
+
category?: string;
|
|
37
|
+
author?: {
|
|
38
|
+
name?: string;
|
|
39
|
+
bio?: string;
|
|
40
|
+
avatarUrl?: string;
|
|
41
|
+
};
|
|
42
|
+
relatedPosts?: Array<{
|
|
43
|
+
title: string;
|
|
44
|
+
url?: string;
|
|
45
|
+
excerpt?: string;
|
|
46
|
+
}>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Options threaded to every section renderer.
|
|
50
|
+
*
|
|
51
|
+
* `sanitizeHtml` is applied to author-supplied HTML (e.g. the `article-body`
|
|
52
|
+
* section) before it is injected via `dangerouslySetInnerHTML`.
|
|
53
|
+
*
|
|
54
|
+
* SECURITY: the default is the identity function because Actuate sanitizes
|
|
55
|
+
* rich text on **write** (cms-core `sanitizeHtml`, the allow-list source of
|
|
56
|
+
* truth). If you render HTML from an untrusted or third-party source, OR want
|
|
57
|
+
* defense-in-depth, pass a sanitizer here — e.g.
|
|
58
|
+
* `import { sanitizeHtml } from '@actuate-media/cms-core'` in a server
|
|
59
|
+
* component, or any DOMPurify-style function.
|
|
60
|
+
*/
|
|
61
|
+
export interface RenderOptions {
|
|
62
|
+
sanitizeHtml?: (html: string) => string;
|
|
63
|
+
}
|
|
64
|
+
/** Internal: options with all defaults resolved. */
|
|
65
|
+
export interface ResolvedRenderOptions {
|
|
66
|
+
sanitizeHtml: (html: string) => string;
|
|
67
|
+
}
|
|
68
|
+
/** Props every section renderer receives. */
|
|
69
|
+
export interface SectionRendererProps {
|
|
70
|
+
section: PublicSection;
|
|
71
|
+
ctx?: PostContext;
|
|
72
|
+
options: ResolvedRenderOptions;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* A section renderer: maps one section's content to React. Renderers must be
|
|
76
|
+
* SSR-safe (no browser-only APIs at module/render time) so they work in React
|
|
77
|
+
* Server Components.
|
|
78
|
+
*/
|
|
79
|
+
export type SectionRenderer = (props: SectionRendererProps) => ReactNode;
|
|
80
|
+
/** A map of section-type id → renderer (used for overrides + the defaults). */
|
|
81
|
+
export type SectionRendererMap = Record<string, SectionRenderer>;
|
|
82
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,oEAAoE;AACpE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,qFAAqF;IACrF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5D,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACxE;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CACxC;AAED,oDAAoD;AACpD,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CACvC;AAED,6CAA6C;AAC7C,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,aAAa,CAAA;IACtB,GAAG,CAAC,EAAE,WAAW,CAAA;IACjB,OAAO,EAAE,qBAAqB,CAAA;CAC/B;AAED;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,oBAAoB,KAAK,SAAS,CAAA;AAExE,+EAA+E;AAC/E,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small, pure helpers shared by the default section renderers. No DOM or
|
|
3
|
+
* browser APIs — these run in React Server Components.
|
|
4
|
+
*/
|
|
5
|
+
/** Read a string field from a section's content, with a fallback. */
|
|
6
|
+
export declare function str(content: Record<string, unknown> | undefined, key: string, fallback?: string): string;
|
|
7
|
+
/** Read a boolean field from a section's content, with a fallback. */
|
|
8
|
+
export declare function bool(content: Record<string, unknown> | undefined, key: string, fallback?: boolean): boolean;
|
|
9
|
+
/** Read an array-of-records field (e.g. `stats`, `images`) defensively. */
|
|
10
|
+
export declare function rows(content: Record<string, unknown> | undefined, key: string): Array<Record<string, unknown>>;
|
|
11
|
+
/** Vertical padding utility class from a section's `paddingY` setting. */
|
|
12
|
+
export declare function paddingClass(settings: Record<string, unknown> | undefined): string;
|
|
13
|
+
/** Background + text-color utility classes from a section's background settings. */
|
|
14
|
+
export declare function backgroundClass(settings: Record<string, unknown> | undefined): string;
|
|
15
|
+
/** True when a section uses a dark (purple) background — drives button tone. */
|
|
16
|
+
export declare function isDark(settings: Record<string, unknown> | undefined): boolean;
|
|
17
|
+
/** Format an ISO date for a post header; empty string when missing/invalid. */
|
|
18
|
+
export declare function formatHeaderDate(value?: string | null): string;
|
|
19
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qEAAqE;AACrE,wBAAgB,GAAG,CACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC5C,GAAG,EAAE,MAAM,EACX,QAAQ,SAAK,GACZ,MAAM,CAGR;AAED,sEAAsE;AACtE,wBAAgB,IAAI,CAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC5C,GAAG,EAAE,MAAM,EACX,QAAQ,UAAQ,GACf,OAAO,CAGT;AAED,2EAA2E;AAC3E,wBAAgB,IAAI,CAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC5C,GAAG,EAAE,MAAM,GACV,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAGhC;AAED,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,CAWlF;AAED,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,CASrF;AAED,gFAAgF;AAChF,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,OAAO,CAK7E;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAK9D"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small, pure helpers shared by the default section renderers. No DOM or
|
|
3
|
+
* browser APIs — these run in React Server Components.
|
|
4
|
+
*/
|
|
5
|
+
/** Read a string field from a section's content, with a fallback. */
|
|
6
|
+
export function str(content, key, fallback = '') {
|
|
7
|
+
const v = content?.[key];
|
|
8
|
+
return typeof v === 'string' ? v : fallback;
|
|
9
|
+
}
|
|
10
|
+
/** Read a boolean field from a section's content, with a fallback. */
|
|
11
|
+
export function bool(content, key, fallback = false) {
|
|
12
|
+
const v = content?.[key];
|
|
13
|
+
return typeof v === 'boolean' ? v : fallback;
|
|
14
|
+
}
|
|
15
|
+
/** Read an array-of-records field (e.g. `stats`, `images`) defensively. */
|
|
16
|
+
export function rows(content, key) {
|
|
17
|
+
const v = content?.[key];
|
|
18
|
+
return Array.isArray(v) ? v : [];
|
|
19
|
+
}
|
|
20
|
+
/** Vertical padding utility class from a section's `paddingY` setting. */
|
|
21
|
+
export function paddingClass(settings) {
|
|
22
|
+
switch (settings?.paddingY) {
|
|
23
|
+
case 'sm':
|
|
24
|
+
return 'py-8';
|
|
25
|
+
case 'md':
|
|
26
|
+
return 'py-12';
|
|
27
|
+
case 'xl':
|
|
28
|
+
return 'py-20 sm:py-28';
|
|
29
|
+
default:
|
|
30
|
+
return 'py-16 sm:py-20';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** Background + text-color utility classes from a section's background settings. */
|
|
34
|
+
export function backgroundClass(settings) {
|
|
35
|
+
const type = settings?.backgroundType;
|
|
36
|
+
const color = settings?.backgroundColor;
|
|
37
|
+
if (type === 'gradient' && color === 'purple') {
|
|
38
|
+
return 'bg-gradient-to-br from-violet-600 to-violet-700 text-white';
|
|
39
|
+
}
|
|
40
|
+
if (type === 'solid' && color === 'purple')
|
|
41
|
+
return 'bg-violet-600 text-white';
|
|
42
|
+
if (type === 'solid' && color === 'muted')
|
|
43
|
+
return 'bg-zinc-50 text-zinc-900';
|
|
44
|
+
return 'bg-white text-zinc-900';
|
|
45
|
+
}
|
|
46
|
+
/** True when a section uses a dark (purple) background — drives button tone. */
|
|
47
|
+
export function isDark(settings) {
|
|
48
|
+
return ((settings?.backgroundType === 'solid' || settings?.backgroundType === 'gradient') &&
|
|
49
|
+
settings?.backgroundColor === 'purple');
|
|
50
|
+
}
|
|
51
|
+
/** Format an ISO date for a post header; empty string when missing/invalid. */
|
|
52
|
+
export function formatHeaderDate(value) {
|
|
53
|
+
if (!value)
|
|
54
|
+
return '';
|
|
55
|
+
const d = new Date(value);
|
|
56
|
+
if (Number.isNaN(d.getTime()))
|
|
57
|
+
return '';
|
|
58
|
+
return d.toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' });
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qEAAqE;AACrE,MAAM,UAAU,GAAG,CACjB,OAA4C,EAC5C,GAAW,EACX,QAAQ,GAAG,EAAE;IAEb,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,CAAC,CAAA;IACxB,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;AAC7C,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,IAAI,CAClB,OAA4C,EAC5C,GAAW,EACX,QAAQ,GAAG,KAAK;IAEhB,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,CAAC,CAAA;IACxB,OAAO,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;AAC9C,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,IAAI,CAClB,OAA4C,EAC5C,GAAW;IAEX,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,CAAC,CAAA;IACxB,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAoC,CAAC,CAAC,CAAC,EAAE,CAAA;AACtE,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,YAAY,CAAC,QAA6C;IACxE,QAAQ,QAAQ,EAAE,QAAQ,EAAE,CAAC;QAC3B,KAAK,IAAI;YACP,OAAO,MAAM,CAAA;QACf,KAAK,IAAI;YACP,OAAO,OAAO,CAAA;QAChB,KAAK,IAAI;YACP,OAAO,gBAAgB,CAAA;QACzB;YACE,OAAO,gBAAgB,CAAA;IAC3B,CAAC;AACH,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,eAAe,CAAC,QAA6C;IAC3E,MAAM,IAAI,GAAG,QAAQ,EAAE,cAAc,CAAA;IACrC,MAAM,KAAK,GAAG,QAAQ,EAAE,eAAe,CAAA;IACvC,IAAI,IAAI,KAAK,UAAU,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9C,OAAO,4DAA4D,CAAA;IACrE,CAAC;IACD,IAAI,IAAI,KAAK,OAAO,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,0BAA0B,CAAA;IAC7E,IAAI,IAAI,KAAK,OAAO,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,0BAA0B,CAAA;IAC5E,OAAO,wBAAwB,CAAA;AACjC,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,MAAM,CAAC,QAA6C;IAClE,OAAO,CACL,CAAC,QAAQ,EAAE,cAAc,KAAK,OAAO,IAAI,QAAQ,EAAE,cAAc,KAAK,UAAU,CAAC;QACjF,QAAQ,EAAE,eAAe,KAAK,QAAQ,CACvC,CAAA;AACH,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,gBAAgB,CAAC,KAAqB;IACpD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAA;IACrB,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAA;IACzB,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,EAAE,CAAA;IACxC,OAAO,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAA;AAC5F,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@actuate-media/sections-react",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Public React renderer for Actuate CMS page sections — the canonical PageSection[] contract — with a consumer-controlled renderer registry.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/actuate-media/actuatecms.git",
|
|
8
|
+
"directory": "packages/sections-react"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"sideEffects": false,
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"default": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@actuate-media/cms-core": "0.48.0"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"react": ">=18.0.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/react": "^19.0.0",
|
|
35
|
+
"react": "^19.2.0",
|
|
36
|
+
"react-dom": "^19.2.0",
|
|
37
|
+
"@types/react-dom": "^19.0.0",
|
|
38
|
+
"typescript": "^5.7.0",
|
|
39
|
+
"vitest": "^4.1.0"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=20"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsc --project tsconfig.json",
|
|
46
|
+
"dev": "tsc --project tsconfig.json --watch --preserveWatchOutput",
|
|
47
|
+
"type-check": "tsc --noEmit",
|
|
48
|
+
"test": "vitest run",
|
|
49
|
+
"clean": "rm -rf dist .turbo"
|
|
50
|
+
}
|
|
51
|
+
}
|