@sonordev/site-kit 8.1.0 → 8.3.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/AGENTS.md +13 -1
- package/CHANGELOG.md +11 -0
- package/README.md +9 -5
- package/agent-manifest.json +47 -8
- package/dist/{AnalyticsProvider-UWTCE5UO.js → AnalyticsProvider-QXO33JUF.js} +6 -6
- package/dist/{ArticleFaqSection-3Q26DP7P.js → ArticleFaqSection-DEWE5B4Q.js} +1 -1
- package/dist/{ArticleViewTracker-MYD6SGNH.js → ArticleViewTracker-KN6ENIRS.js} +17 -6
- package/dist/{BlocksPopup-OY5G3EFH.js → BlocksPopup-3RPN6YVJ.js} +6 -6
- package/dist/{ChatWidget-BTR5VERC.js → ChatWidget-D2X445PO.js} +6 -6
- package/dist/{FileField-DEHVYXAO.js → FileField-UNGSNGJ5.js} +4 -4
- package/dist/{FormSpotlight-VGC4CZL4.js → FormSpotlight-JFH2ENKQ.js} +1 -1
- package/dist/{FormStage-CJUSCSAL.js → FormStage-RC3WHHXP.js} +1 -1
- package/dist/{ManagedForm-JCI2KPMO.js → ManagedForm-FOQZ2IYG.js} +7 -7
- package/dist/{ManagedNewsletterForm-DTE4KKXV.js → ManagedNewsletterForm-NFNF33V3.js} +16 -7
- package/dist/{SignalCore-LGCBQDEH.js → SignalCore-5KABGX5C.js} +4 -4
- package/dist/SiteChat-JQ46ZIJ4.js +6 -0
- package/dist/SiteDesignReporter-N7L6DR4J.js +12 -0
- package/dist/{SitePopups-T6YPHAVY.js → SitePopups-WZBKX5Q3.js} +6 -6
- package/dist/SitemapSync-GY6UADRI.js +9 -0
- package/dist/_client/booking-widget.js +6 -6
- package/dist/_client/testimonial-section.js +3 -3
- package/dist/affiliates/index.js +4 -4
- package/dist/analytics/index.js +6 -6
- package/dist/{article-styles-GGZOQG5X.js → article-styles-7QONZJR5.js} +3 -3
- package/dist/article-tables-6XHVULPU.js +2 -0
- package/dist/articles/Article.d.ts +2 -89
- package/dist/articles/ArticleFAQ.d.ts +2 -41
- package/dist/articles/ArticleFaqSection.d.ts +2 -2
- package/dist/articles/ArticleList.d.ts +2 -79
- package/dist/articles/ArticleViewTracker.d.ts +2 -15
- package/dist/articles/AuthorCard.d.ts +2 -10
- package/dist/articles/AuthorPage.d.ts +2 -8
- package/dist/articles/ClusterLandingPage.d.ts +2 -40
- package/dist/articles/ClusterNavigation.d.ts +2 -37
- package/dist/articles/ManagedNewsletterForm.d.ts +3 -12
- package/dist/articles/NewsletterShell.d.ts +2 -17
- package/dist/articles/NewsletterWidget.d.ts +2 -30
- package/dist/articles/PublicationLayout.d.ts +2 -67
- package/dist/articles/PublicationSidebar.d.ts +2 -36
- package/dist/articles/RelatedPosts.d.ts +2 -22
- package/dist/articles/ServiceCallout.d.ts +2 -56
- package/dist/articles/TableOfContents.d.ts +2 -6
- package/dist/articles/article-photos.d.ts +2 -9
- package/dist/articles/article-styles.d.ts +2 -21
- package/dist/articles/article-tables.d.ts +2 -12
- package/dist/articles/artwork.d.ts +2 -13
- package/dist/articles/author-schema.d.ts +2 -72
- package/dist/articles/author-social.d.ts +2 -14
- package/dist/articles/excerpt.d.ts +2 -17
- package/dist/articles/index.d.ts +2 -79
- package/dist/articles/index.js +16 -11
- package/dist/articles/news-sitemap.d.ts +2 -46
- package/dist/articles/processArticleHtml.d.ts +2 -34
- package/dist/articles/public-reads.d.ts +2 -26
- package/dist/articles/reading-time.d.ts +2 -9
- package/dist/articles/routes.d.ts +2 -52
- package/dist/articles/server-core.d.ts +2 -461
- package/dist/articles/server-ui.d.ts +2 -30
- package/dist/articles/server-ui.js +26 -17
- package/dist/articles/server.d.ts +2 -461
- package/dist/articles/server.js +14 -5
- package/dist/articles/types.d.ts +2 -315
- package/dist/articles/widget-styles.d.ts +2 -8
- package/dist/chat/index.js +8 -8
- package/dist/{chunk-AIDIEVPZ.js → chunk-2JMCBJM5.js} +1 -1
- package/dist/chunk-34ZYJTQR.js +1 -0
- package/dist/{chunk-ADI6IYFH.js → chunk-3OY52UFM.js} +1 -1
- package/dist/{chunk-WMVK77ND.js → chunk-4K735O3J.js} +1 -1
- package/dist/{chunk-55GHBRCN.js → chunk-4PVMUPC6.js} +2 -2
- package/dist/{chunk-L5UOHS6E.js → chunk-5D7ZISUP.js} +1 -1
- package/dist/{chunk-JT52KYHQ.js → chunk-5RYSTKVU.js} +1 -1
- package/dist/{chunk-6CJGZFOU.js → chunk-A4MPHIVP.js} +1 -1
- package/dist/chunk-B7T2SFUF.js +1 -0
- package/dist/{chunk-FV2VD7WM.js → chunk-BC7JMY4Z.js} +3 -3
- package/dist/{chunk-255NCCPB.js → chunk-BOCYBDKV.js} +1 -1
- package/dist/{chunk-NFRJTOTB.js → chunk-BSQP6PRA.js} +1 -1
- package/dist/{chunk-GKGSXUVQ.js → chunk-BVB5FBAA.js} +1 -1
- package/dist/{chunk-NWVB75ER.js → chunk-C2UROFGZ.js} +1 -1
- package/dist/{chunk-F2VYN3QL.js → chunk-C4AFNZT2.js} +1 -1
- package/dist/{chunk-GC2QWXJ3.js → chunk-D6ZIQMHB.js} +3 -3
- package/dist/{chunk-GYF2ULVO.js → chunk-DJAYFHVF.js} +1 -1
- package/dist/{chunk-XUCU3LX4.js → chunk-DPSNMOMZ.js} +1 -1
- package/dist/{chunk-A3EU6HB5.js → chunk-E3UR37RX.js} +2 -2
- package/dist/{chunk-Y3INC4QJ.js → chunk-E4PTMORJ.js} +1 -1
- package/dist/{chunk-TAO6BVA2.js → chunk-EA6FZMYA.js} +2 -2
- package/dist/{chunk-V56RZH7J.js → chunk-FHUTOXS7.js} +1 -1
- package/dist/{chunk-LLW5HKEE.js → chunk-GKJVSZ7H.js} +3 -3
- package/dist/chunk-H72ZFO3F.js +1 -0
- package/dist/{chunk-CSTC6HZO.js → chunk-HND6BDXC.js} +3 -3
- package/dist/chunk-IEGDPRQB.js +14 -0
- package/dist/{chunk-CAH4Y4PY.js → chunk-JO76F5WP.js} +1 -1
- package/dist/{chunk-4Z3DI2EL.js → chunk-KJVUOJMW.js} +58 -58
- package/dist/{chunk-SC4MZGWZ.js → chunk-LBDWAXAO.js} +1 -1
- package/dist/{chunk-RSBMQFZW.js → chunk-LPKKSYKX.js} +3 -3
- package/dist/{chunk-2UO4HPGE.js → chunk-M5SF7NCC.js} +73 -51
- package/dist/{chunk-S6IGQYHW.js → chunk-MQ4REMTH.js} +2 -2
- package/dist/{chunk-O4DETQJI.js → chunk-NA4Z4CQG.js} +1 -1
- package/dist/{chunk-WPOFTCKL.js → chunk-OIWFXUVD.js} +2 -2
- package/dist/{chunk-G2HCCWZQ.js → chunk-QBCWVT2S.js} +2 -2
- package/dist/{chunk-DZV3KPVF.js → chunk-QCZHYO5M.js} +1 -1
- package/dist/{chunk-DOMBP3FW.js → chunk-QDILCQBL.js} +9 -9
- package/dist/{chunk-IAYGTQJD.js → chunk-SCTVADDL.js} +2 -2
- package/dist/{chunk-QXMIKDOL.js → chunk-SNRE3ZVZ.js} +3 -3
- package/dist/{chunk-DSNCU2E3.js → chunk-TT4JZDKM.js} +3 -3
- package/dist/{chunk-6VHDCJIZ.js → chunk-U7Y3QG3A.js} +1 -1
- package/dist/{chunk-3G7YABRA.js → chunk-W7OPEMGJ.js} +4 -1
- package/dist/{chunk-2JEUDTL6.js → chunk-WBUG7XRL.js} +2 -2
- package/dist/{chunk-47VB5INH.js → chunk-WSOZ3FQN.js} +1 -1
- package/dist/chunk-X4IJS7LV.js +319 -0
- package/dist/{chunk-JIH32RH2.js → chunk-XA7Q2VQA.js} +1 -1
- package/dist/{chunk-5L467Z5Q.js → chunk-XLAXYPTK.js} +3 -3
- package/dist/client/index.js +4 -16
- package/dist/contracts/editorial-media.d.ts +39 -0
- package/dist/contracts/entries.d.ts +1 -1
- package/dist/fleet/index.js +6 -6
- package/dist/forms/index.js +9 -325
- package/dist/forms/server.js +2 -2
- package/dist/images/index.js +4 -4
- package/dist/index.js +1 -1
- package/dist/layout/client.js +9 -9
- package/dist/layout/index.js +10 -10
- package/dist/llms/index.js +8 -8
- package/dist/maps/index.js +4 -4
- package/dist/mcp/sonor.d.ts +42 -3
- package/dist/mcp/sonor.js +25 -20
- package/dist/mcp/transport.d.ts +1 -1
- package/dist/press-kit/articles/Article.d.ts +89 -0
- package/dist/press-kit/articles/ArticleFAQ.d.ts +41 -0
- package/dist/press-kit/articles/ArticleFaqSection.d.ts +2 -0
- package/dist/press-kit/articles/ArticleList.d.ts +79 -0
- package/dist/press-kit/articles/ArticleViewTracker.d.ts +15 -0
- package/dist/press-kit/articles/AuthorCard.d.ts +10 -0
- package/dist/press-kit/articles/AuthorPage.d.ts +8 -0
- package/dist/press-kit/articles/ClusterLandingPage.d.ts +40 -0
- package/dist/press-kit/articles/ClusterNavigation.d.ts +37 -0
- package/dist/press-kit/articles/ManagedNewsletterForm.d.ts +12 -0
- package/dist/press-kit/articles/NewsletterShell.d.ts +17 -0
- package/dist/press-kit/articles/NewsletterWidget.d.ts +30 -0
- package/dist/press-kit/articles/PublicationLayout.d.ts +67 -0
- package/dist/press-kit/articles/PublicationSidebar.d.ts +36 -0
- package/dist/press-kit/articles/RelatedPosts.d.ts +22 -0
- package/dist/press-kit/articles/ServiceCallout.d.ts +56 -0
- package/dist/press-kit/articles/TableOfContents.d.ts +6 -0
- package/dist/press-kit/articles/article-photos.d.ts +9 -0
- package/dist/press-kit/articles/article-styles.d.ts +21 -0
- package/dist/press-kit/articles/article-tables.d.ts +12 -0
- package/dist/press-kit/articles/artwork.d.ts +13 -0
- package/dist/press-kit/articles/author-schema.d.ts +72 -0
- package/dist/press-kit/articles/author-social.d.ts +14 -0
- package/dist/press-kit/articles/excerpt.d.ts +17 -0
- package/dist/press-kit/articles/index.d.ts +79 -0
- package/dist/press-kit/articles/news-sitemap.d.ts +46 -0
- package/dist/press-kit/articles/processArticleHtml.d.ts +34 -0
- package/dist/press-kit/articles/public-reads.d.ts +26 -0
- package/dist/press-kit/articles/reading-time.d.ts +9 -0
- package/dist/press-kit/articles/routes.d.ts +52 -0
- package/dist/press-kit/articles/server-core.d.ts +461 -0
- package/dist/press-kit/articles/server-ui.d.ts +31 -0
- package/dist/press-kit/articles/types.d.ts +316 -0
- package/dist/press-kit/articles/widget-styles.d.ts +8 -0
- package/dist/reputation/index.js +3 -3
- package/dist/reputation/server.js +2 -2
- package/dist/revalidate/index.js +2 -2
- package/dist/runtime/index.js +5 -4
- package/dist/seo/client.js +6 -6
- package/dist/seo/index.js +7 -7
- package/dist/seo/llms.js +8 -8
- package/dist/seo/register-sitemap-cli.js +1 -1
- package/dist/seo/sitemap.js +6 -6
- package/dist/server/index.js +3 -2
- package/dist/shared/build-entries.d.ts +2 -1
- package/dist/shared/clientApiConfig.d.ts +2 -0
- package/dist/shared/import-specifiers.d.ts +1 -1
- package/dist/shared/index.d.ts +6 -0
- package/dist/shared/index.js +8 -0
- package/dist/shared/version.d.ts +1 -1
- package/dist/signal/index.js +2 -2
- package/dist/sitemap/index.js +6 -6
- package/dist/sync/index.js +6 -6
- package/dist/website/images.js +4 -4
- package/dist/website/index.js +7 -7
- package/dist/website/popups.js +6 -6
- package/dist/{writeLLMsTxt-OS2WBSLM.js → writeLLMsTxt-VKHCM5IS.js} +5 -5
- package/docs/MIGRATING-TO-PRESS-KIT.md +83 -0
- package/docs.json +145 -29
- package/package.json +15 -5
- package/src/articles/README.md +5 -360
- package/src/mcp/README.md +16 -0
- package/src/og/README.md +1 -1
- package/src/runtime/README.md +4 -0
- package/dist/SiteChat-6SF7PVUT.js +0 -6
- package/dist/SiteDesignReporter-VISQZ5NQ.js +0 -12
- package/dist/SitemapSync-VKMVRPZL.js +0 -9
- package/dist/article-tables-AXSZOGNW.js +0 -2
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/press-kit/articles - Article Component
|
|
3
|
+
*
|
|
4
|
+
* Fetches and displays a single article with full content, table of contents,
|
|
5
|
+
* author info, related posts, and SEO metadata support.
|
|
6
|
+
*
|
|
7
|
+
* Ships with world-class default styling via scoped `.sk-article-*` classes.
|
|
8
|
+
* No configuration needed — just `<Article slug={slug} />`.
|
|
9
|
+
*
|
|
10
|
+
* Override with `styles` prop (per-element class names) or `unstyled` for
|
|
11
|
+
* complete control. The `children` render prop gives full data access.
|
|
12
|
+
*/
|
|
13
|
+
import React from 'react';
|
|
14
|
+
import type { Article as ArticleType, TocItem } from './types';
|
|
15
|
+
import { type PublicationRoutingOptions } from './routes';
|
|
16
|
+
export interface ArticleStyles {
|
|
17
|
+
article?: string;
|
|
18
|
+
header?: string;
|
|
19
|
+
breadcrumb?: string;
|
|
20
|
+
breadcrumbLink?: string;
|
|
21
|
+
title?: string;
|
|
22
|
+
subtitle?: string;
|
|
23
|
+
meta?: string;
|
|
24
|
+
metaItem?: string;
|
|
25
|
+
featuredImageWrapper?: string;
|
|
26
|
+
featuredImage?: string;
|
|
27
|
+
contentLayout?: string;
|
|
28
|
+
content?: string;
|
|
29
|
+
tocSidebar?: string;
|
|
30
|
+
tocTitle?: string;
|
|
31
|
+
tocList?: string;
|
|
32
|
+
tocItem?: string;
|
|
33
|
+
tocLink?: string;
|
|
34
|
+
tags?: string;
|
|
35
|
+
tag?: string;
|
|
36
|
+
faqSection?: string;
|
|
37
|
+
faqTitle?: string;
|
|
38
|
+
faqItem?: string;
|
|
39
|
+
faqQuestion?: string;
|
|
40
|
+
faqAnswer?: string;
|
|
41
|
+
authorCard?: string;
|
|
42
|
+
relatedSection?: string;
|
|
43
|
+
relatedTitle?: string;
|
|
44
|
+
relatedGrid?: string;
|
|
45
|
+
relatedCard?: string;
|
|
46
|
+
notFound?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface ArticleServerProps {
|
|
49
|
+
apiUrl?: string;
|
|
50
|
+
apiKey?: string;
|
|
51
|
+
slug: string;
|
|
52
|
+
showToc?: boolean;
|
|
53
|
+
showRelated?: boolean;
|
|
54
|
+
relatedCount?: number;
|
|
55
|
+
showAuthor?: boolean;
|
|
56
|
+
basePath?: string;
|
|
57
|
+
routing?: PublicationRoutingOptions;
|
|
58
|
+
/** The publication's name in the breadcrumb (e.g. "The Forge"). Default "Articles". */
|
|
59
|
+
publicationName?: string;
|
|
60
|
+
className?: string;
|
|
61
|
+
styles?: ArticleStyles;
|
|
62
|
+
unstyled?: boolean;
|
|
63
|
+
siteUrl?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Sub-site host for multi-site projects (e.g. `charlotte.example.com`). Scopes
|
|
66
|
+
* the post, related-posts and view-count calls to that host. Omit to resolve
|
|
67
|
+
* from NEXT_PUBLIC_SITE_URL. Separate from `siteUrl`, which only decides
|
|
68
|
+
* which links in the body open in a new tab.
|
|
69
|
+
*/
|
|
70
|
+
site?: string;
|
|
71
|
+
/**
|
|
72
|
+
* What to render when the post doesn't exist. Default true: call Next's
|
|
73
|
+
* `notFound()`, so the route answers 404 with `noindex` instead of a
|
|
74
|
+
* "Post Not Found" message on a 200 (a soft 404). False renders that
|
|
75
|
+
* message, for a page that wants its own missing-post state.
|
|
76
|
+
*
|
|
77
|
+
* For a guaranteed 404 status, also call `requireArticle(slug)` from
|
|
78
|
+
* `@sonordev/press-kit/articles/server` in `generateMetadata`: metadata resolves
|
|
79
|
+
* before anything streams. Thrown from inside a Suspense boundary that has
|
|
80
|
+
* already streamed, `notFound()` can only add `noindex` to a 200.
|
|
81
|
+
*/
|
|
82
|
+
notFound?: boolean;
|
|
83
|
+
children?: (props: {
|
|
84
|
+
post: ArticleType;
|
|
85
|
+
tableOfContents: TocItem[];
|
|
86
|
+
relatedPosts: ArticleType[];
|
|
87
|
+
}) => React.ReactNode;
|
|
88
|
+
}
|
|
89
|
+
export declare function Article({ apiUrl, apiKey, slug, showToc, showRelated, relatedCount, showAuthor, basePath, publicationName, routing, className, styles, unstyled, siteUrl, site, notFound, children, }: ArticleServerProps): Promise<React.JSX.Element | null>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/press-kit/articles - Article FAQ Component
|
|
3
|
+
*
|
|
4
|
+
* Renders FAQ items with collapsible accordion behavior.
|
|
5
|
+
* Content is always in the DOM (not display:none) for SEO crawlability.
|
|
6
|
+
* Uses CSS max-height transitions — no JS animation library required.
|
|
7
|
+
*
|
|
8
|
+
* Pairs with FAQPage schema (generated by Signal AI in the publication pipeline)
|
|
9
|
+
* for Google's "People Also Ask" featured snippets.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <ArticleFAQ items={post.faqItems} />
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
import React from 'react';
|
|
17
|
+
export interface FaqItem {
|
|
18
|
+
question: string;
|
|
19
|
+
answer: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ArticleFAQProps {
|
|
22
|
+
items: FaqItem[];
|
|
23
|
+
/** Section title */
|
|
24
|
+
title?: string;
|
|
25
|
+
/** Allow multiple items open simultaneously */
|
|
26
|
+
allowMultiple?: boolean;
|
|
27
|
+
/** Override styles with Tailwind classes */
|
|
28
|
+
styles?: {
|
|
29
|
+
section?: string;
|
|
30
|
+
title?: string;
|
|
31
|
+
list?: string;
|
|
32
|
+
item?: string;
|
|
33
|
+
question?: string;
|
|
34
|
+
questionText?: string;
|
|
35
|
+
icon?: string;
|
|
36
|
+
answer?: string;
|
|
37
|
+
answerInner?: string;
|
|
38
|
+
};
|
|
39
|
+
unstyled?: boolean;
|
|
40
|
+
}
|
|
41
|
+
export declare function ArticleFAQ({ items, title, allowMultiple, styles, unstyled, }: ArticleFAQProps): React.JSX.Element | null;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/press-kit/articles - Article List Component
|
|
3
|
+
*
|
|
4
|
+
* Fetches and displays a list of articles with pagination, filtering, and sorting.
|
|
5
|
+
*
|
|
6
|
+
* Ships with world-class default styling via scoped `.sk-article-list-*` classes.
|
|
7
|
+
* No configuration needed — just `<ArticleList basePath="/article" />`.
|
|
8
|
+
*
|
|
9
|
+
* Override with `styles` prop (per-element class names) or `unstyled` for
|
|
10
|
+
* complete control. The `children` render prop gives full data access.
|
|
11
|
+
*/
|
|
12
|
+
import React from 'react';
|
|
13
|
+
import type { ArticleListResult, Article, ArticleCategory } from './types';
|
|
14
|
+
import { type PublicationRoutingOptions } from './routes';
|
|
15
|
+
export interface ArticleListStyles {
|
|
16
|
+
container?: string;
|
|
17
|
+
categoryNav?: string;
|
|
18
|
+
categoryLink?: string;
|
|
19
|
+
categoryLinkActive?: string;
|
|
20
|
+
categoryLinkInactive?: string;
|
|
21
|
+
grid?: string;
|
|
22
|
+
card?: string;
|
|
23
|
+
cardImageWrapper?: string;
|
|
24
|
+
cardImage?: string;
|
|
25
|
+
cardBody?: string;
|
|
26
|
+
cardMeta?: string;
|
|
27
|
+
cardCategory?: string;
|
|
28
|
+
cardDate?: string;
|
|
29
|
+
cardTitle?: string;
|
|
30
|
+
cardTitleLink?: string;
|
|
31
|
+
cardExcerpt?: string;
|
|
32
|
+
cardFooter?: string;
|
|
33
|
+
cardAuthor?: string;
|
|
34
|
+
cardReadingTime?: string;
|
|
35
|
+
cardReadMore?: string;
|
|
36
|
+
pagination?: string;
|
|
37
|
+
paginationLink?: string;
|
|
38
|
+
paginationInfo?: string;
|
|
39
|
+
emptyState?: string;
|
|
40
|
+
}
|
|
41
|
+
export interface ArticleListServerProps {
|
|
42
|
+
apiUrl?: string;
|
|
43
|
+
apiKey?: string;
|
|
44
|
+
category?: string;
|
|
45
|
+
tag?: string;
|
|
46
|
+
/** Author slug (preferred) or display name; slug filtering requires the current Sonor API */
|
|
47
|
+
author?: string;
|
|
48
|
+
featured?: boolean;
|
|
49
|
+
search?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Topic cluster slug — pairs with getTopicCluster. Note: an unknown slug
|
|
52
|
+
* yields an UNfiltered list (pre-existing API behavior).
|
|
53
|
+
*/
|
|
54
|
+
cluster?: string;
|
|
55
|
+
page?: number;
|
|
56
|
+
perPage?: number;
|
|
57
|
+
orderBy?: 'published_at' | 'title' | 'view_count';
|
|
58
|
+
order?: 'asc' | 'desc';
|
|
59
|
+
/**
|
|
60
|
+
* Sub-site host for multi-site projects (e.g. `charlotte.example.com`): the list
|
|
61
|
+
* shows that host's posts plus project-wide ones. Omit to resolve from
|
|
62
|
+
* NEXT_PUBLIC_SITE_URL.
|
|
63
|
+
*/
|
|
64
|
+
site?: string;
|
|
65
|
+
showCategoryFilter?: boolean;
|
|
66
|
+
showPagination?: boolean;
|
|
67
|
+
className?: string;
|
|
68
|
+
basePath?: string;
|
|
69
|
+
routing?: PublicationRoutingOptions;
|
|
70
|
+
styles?: ArticleListStyles;
|
|
71
|
+
unstyled?: boolean;
|
|
72
|
+
renderPost?: (post: Article) => React.ReactNode;
|
|
73
|
+
children?: (props: {
|
|
74
|
+
posts: Article[];
|
|
75
|
+
pagination: ArticleListResult['pagination'];
|
|
76
|
+
categories: ArticleCategory[];
|
|
77
|
+
}) => React.ReactNode;
|
|
78
|
+
}
|
|
79
|
+
export declare function ArticleList({ apiUrl, apiKey, category, tag, author, featured, search, cluster, page, perPage, orderBy, order, site, showCategoryFilter, showPagination, className, basePath, routing, styles, unstyled, renderPost, children, }: ArticleListServerProps): Promise<string | number | bigint | boolean | React.JSX.Element | Iterable<React.ReactNode> | null | undefined>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface ArticleViewTrackerProps {
|
|
2
|
+
slug: string;
|
|
3
|
+
/**
|
|
4
|
+
* Sub-site host the view counts toward. Omit to use the host SiteKitLayout
|
|
5
|
+
* published (`__SITE_KIT_SITE__`, the same one analytics tags page views
|
|
6
|
+
* with), then NEXT_PUBLIC_SITE_URL, then `window.location.host`.
|
|
7
|
+
*/
|
|
8
|
+
site?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The effect body, exported for tests (the package's vitest runs in node, so
|
|
12
|
+
* the component's mount path can't be exercised directly).
|
|
13
|
+
*/
|
|
14
|
+
export declare function trackArticleView(slug: string, site?: string): void;
|
|
15
|
+
export declare function ArticleViewTracker({ slug, site }: ArticleViewTrackerProps): null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/press-kit/articles - Author Card Component
|
|
3
|
+
*/
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import type { AuthorCardProps, ArticleAuthor } from './types';
|
|
6
|
+
declare function TrustBlock({ author }: {
|
|
7
|
+
author: ArticleAuthor;
|
|
8
|
+
}): React.JSX.Element | null;
|
|
9
|
+
export declare function AuthorCard({ author, showBio, showSocial, showTrustBlock, className }: AuthorCardProps): React.JSX.Element;
|
|
10
|
+
export { TrustBlock };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/press-kit/articles - Author Page Component (Server Component)
|
|
3
|
+
*
|
|
4
|
+
* Full author profile page with hero, trust block, social links, and articles grid.
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { AuthorPageProps } from './types';
|
|
8
|
+
export declare function AuthorPage({ author, posts, basePath, routing, siteUrl, siteName, jsonLd }: AuthorPageProps): React.JSX.Element;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/press-kit/articles - Cluster Landing Page Component
|
|
3
|
+
*
|
|
4
|
+
* Pre-built page component for `/article/cluster/[slug]` routes.
|
|
5
|
+
* Renders a topic cluster overview with:
|
|
6
|
+
* - Cluster hero (name, topic, description)
|
|
7
|
+
* - Pillar article (featured, large card)
|
|
8
|
+
* - Support articles (grid, categorized by article_type or funnel_stage)
|
|
9
|
+
*
|
|
10
|
+
* Server component — fetches cluster data from Sonor API.
|
|
11
|
+
* Ships with `.sk-cluster-landing-*` scoped styles.
|
|
12
|
+
*/
|
|
13
|
+
import React from 'react';
|
|
14
|
+
import { type PublicationRoutingOptions } from './routes';
|
|
15
|
+
import type { TopicCluster } from './types';
|
|
16
|
+
export interface ClusterLandingPageProps {
|
|
17
|
+
/** Cluster slug to fetch */
|
|
18
|
+
slug: string;
|
|
19
|
+
/** Sub-site host for multi-site projects. Omit to resolve from NEXT_PUBLIC_SITE_URL. */
|
|
20
|
+
site?: string;
|
|
21
|
+
/** Base path for article URLs (default: /article) */
|
|
22
|
+
basePath?: string;
|
|
23
|
+
routing?: PublicationRoutingOptions;
|
|
24
|
+
/**
|
|
25
|
+
* Include each article's own category segment in its URL:
|
|
26
|
+
* {basePath}/{category}/{slug}. Enable on sites whose article routes are
|
|
27
|
+
* category-segmented (e.g. /insights/{category}/{slug}) —
|
|
28
|
+
* without it, links point at {basePath}/{slug} and 404 on such sites.
|
|
29
|
+
*/
|
|
30
|
+
categoryInPath?: boolean;
|
|
31
|
+
/** Disable default styles */
|
|
32
|
+
unstyled?: boolean;
|
|
33
|
+
/** Custom class name */
|
|
34
|
+
className?: string;
|
|
35
|
+
/** Render prop for full data access */
|
|
36
|
+
children?: (props: {
|
|
37
|
+
cluster: TopicCluster;
|
|
38
|
+
}) => React.ReactNode;
|
|
39
|
+
}
|
|
40
|
+
export declare function ClusterLandingPage({ slug, site, basePath, routing, categoryInPath, unstyled, className, children, }: ClusterLandingPageProps): Promise<string | number | bigint | boolean | React.JSX.Element | Iterable<React.ReactNode> | null | undefined>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/press-kit/articles - Cluster Navigation Component
|
|
3
|
+
*
|
|
4
|
+
* Renders cluster context on article pages:
|
|
5
|
+
* - "Full Guide" pillar backlink (on support articles only)
|
|
6
|
+
* - Sibling article list with article_type badges
|
|
7
|
+
*
|
|
8
|
+
* Adapts to light/dark themes automatically using the same --sk-* variables
|
|
9
|
+
* as the rest of site-kit, with currentColor-based fallbacks.
|
|
10
|
+
*/
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import type { ClusterNavigation as ClusterNavigationType } from './types';
|
|
13
|
+
import { type PublicationRoutingOptions } from './routes';
|
|
14
|
+
export interface ClusterNavigationProps {
|
|
15
|
+
/** Cluster navigation data */
|
|
16
|
+
navigation: ClusterNavigationType;
|
|
17
|
+
/** Base path for article URLs (default: /article) */
|
|
18
|
+
basePath?: string;
|
|
19
|
+
routing?: PublicationRoutingOptions;
|
|
20
|
+
/**
|
|
21
|
+
* Fallback category slug for URL building (optional). Each linked article's
|
|
22
|
+
* OWN category takes precedence when present — applying one category to
|
|
23
|
+
* every sibling produced wrong-category URLs (duplicate content / redirect
|
|
24
|
+
* chains) on category-segmented sites whenever a cluster spans categories.
|
|
25
|
+
*/
|
|
26
|
+
category?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Append a trailing slash to article URLs. Defaults to the site's
|
|
29
|
+
* next.config `trailingSlash`, so it rarely needs setting.
|
|
30
|
+
*/
|
|
31
|
+
trailingSlash?: boolean;
|
|
32
|
+
/** Disable default styles */
|
|
33
|
+
unstyled?: boolean;
|
|
34
|
+
/** Custom class name */
|
|
35
|
+
className?: string;
|
|
36
|
+
}
|
|
37
|
+
export declare function ClusterNavigation({ navigation, basePath, routing, category, trailingSlash: trailingSlashProp, unstyled, className, }: ClusterNavigationProps): React.JSX.Element | null;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Managed-forms mode of NewsletterWidget — its own module, loaded via
|
|
3
|
+
* React.lazy, so the useForm graph (forms engine, sonorFetch, site token)
|
|
4
|
+
* stays out of the publication entry's eager bundle. Article consumers only pay for
|
|
5
|
+
* it when a formSlug newsletter actually mounts (enforced by the
|
|
6
|
+
* integration harness's bundle budget, which measures the eager
|
|
7
|
+
* static-import graph).
|
|
8
|
+
*/
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import { type NewsletterShellProps } from './NewsletterShell';
|
|
11
|
+
import type { NewsletterWidgetProps } from './NewsletterWidget';
|
|
12
|
+
export default function ManagedNewsletterForm({ formSlug, title, description, buttonText, successMessage, }: Required<Pick<NewsletterWidgetProps, 'formSlug'>> & Pick<NewsletterShellProps, 'title' | 'description' | 'buttonText' | 'successMessage'>): React.JSX.Element | null;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presentational shell shared by NewsletterWidget's two modes. No data
|
|
3
|
+
* imports — keep it that way, it renders in the eager article bundle.
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
export interface NewsletterShellProps {
|
|
7
|
+
title: string;
|
|
8
|
+
description: string;
|
|
9
|
+
buttonText: string;
|
|
10
|
+
email: string;
|
|
11
|
+
onEmailChange: (value: string) => void;
|
|
12
|
+
onFormSubmit: (e: React.FormEvent) => void;
|
|
13
|
+
status: 'idle' | 'submitting' | 'success' | 'error';
|
|
14
|
+
successMessage: string;
|
|
15
|
+
errorMessage?: string | null;
|
|
16
|
+
}
|
|
17
|
+
export declare function NewsletterShell({ title, description, buttonText, email, onEmailChange, onFormSubmit, status, successMessage, errorMessage, }: NewsletterShellProps): React.JSX.Element;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/site-kit article — newsletter signup widget
|
|
3
|
+
*
|
|
4
|
+
* Two working modes (the old version rendered a form whose submit handler
|
|
5
|
+
* discarded the email):
|
|
6
|
+
*
|
|
7
|
+
* - `onSubmit`: the site owns delivery — we await the callback.
|
|
8
|
+
* - `formSlug`: the widget drives the managed-forms rail (useForm), so
|
|
9
|
+
* submissions inherit Sonor's newsletter routing (email_subscribers),
|
|
10
|
+
* honeypot, reCAPTCHA, and attribution for free.
|
|
11
|
+
*
|
|
12
|
+
* `onSubmit` wins when both are set. With neither, the widget renders
|
|
13
|
+
* nothing and warns — a dead form that swallows emails must not resurrect.
|
|
14
|
+
*
|
|
15
|
+
* Lives in its own module (not PublicationSidebar.tsx) on purpose: it needs hooks,
|
|
16
|
+
* and PublicationSidebar is also bundled into the un-stamped server entry
|
|
17
|
+
* articles/server-ui, where hooks would enter the react-server graph.
|
|
18
|
+
*/
|
|
19
|
+
import React from 'react';
|
|
20
|
+
export interface NewsletterWidgetProps {
|
|
21
|
+
title?: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
buttonText?: string;
|
|
24
|
+
/** Site-owned delivery. Wins over formSlug when both are set. */
|
|
25
|
+
onSubmit?: (email: string) => Promise<void>;
|
|
26
|
+
/** Slug of a managed Sonor form (newsletter routing) to submit through. */
|
|
27
|
+
formSlug?: string;
|
|
28
|
+
successMessage?: string;
|
|
29
|
+
}
|
|
30
|
+
export declare function NewsletterWidget({ title, description, buttonText, onSubmit, formSlug, successMessage, }: NewsletterWidgetProps): React.JSX.Element | null;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/press-kit/articles - Article Layout Component
|
|
3
|
+
*
|
|
4
|
+
* A complete article layout with sidebar, responsive design, and optional hero.
|
|
5
|
+
* Use this to wrap your article pages for consistent styling.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import { PublicationSidebarProps } from './PublicationSidebar';
|
|
9
|
+
import type { PublicationRoutingOptions } from './routes';
|
|
10
|
+
export interface PublicationLayoutProps {
|
|
11
|
+
/** Sonor API URL */
|
|
12
|
+
apiUrl?: string;
|
|
13
|
+
/** Project API key */
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
/** Sub-site host for multi-site projects, passed to the sidebar. Omit to resolve from NEXT_PUBLIC_SITE_URL. */
|
|
16
|
+
site?: string;
|
|
17
|
+
/** Layout style: 'sidebar-right', 'sidebar-left', 'full-width' */
|
|
18
|
+
layout?: 'sidebar-right' | 'sidebar-left' | 'full-width';
|
|
19
|
+
/** Show sidebar */
|
|
20
|
+
showSidebar?: boolean;
|
|
21
|
+
/** Sidebar props */
|
|
22
|
+
sidebarProps?: Partial<PublicationSidebarProps>;
|
|
23
|
+
/** Hero section config */
|
|
24
|
+
hero?: {
|
|
25
|
+
title?: string;
|
|
26
|
+
subtitle?: string;
|
|
27
|
+
backgroundImage?: string;
|
|
28
|
+
backgroundColor?: string;
|
|
29
|
+
};
|
|
30
|
+
/** Max width for content */
|
|
31
|
+
maxWidth?: number;
|
|
32
|
+
/** Base URL for article links */
|
|
33
|
+
basePath?: string;
|
|
34
|
+
routing?: PublicationRoutingOptions;
|
|
35
|
+
/** Custom class name */
|
|
36
|
+
className?: string;
|
|
37
|
+
/** Current category (for sidebar highlighting) */
|
|
38
|
+
currentCategory?: string;
|
|
39
|
+
/** Main content */
|
|
40
|
+
children: React.ReactNode;
|
|
41
|
+
}
|
|
42
|
+
export declare function PublicationLayout({ apiUrl, apiKey, site, layout, showSidebar, sidebarProps, hero, maxWidth, basePath, routing, className, currentCategory, children, }: PublicationLayoutProps): Promise<React.JSX.Element>;
|
|
43
|
+
/**
|
|
44
|
+
* Convenience wrapper for a complete publication index page
|
|
45
|
+
*/
|
|
46
|
+
export interface PublicationPageProps extends Omit<PublicationLayoutProps, 'children'> {
|
|
47
|
+
/** List component to render */
|
|
48
|
+
listComponent: React.ReactNode;
|
|
49
|
+
}
|
|
50
|
+
export declare function PublicationPage({ listComponent, ...layoutProps }: PublicationPageProps): Promise<React.JSX.Element>;
|
|
51
|
+
/**
|
|
52
|
+
* Convenience wrapper for a single article page
|
|
53
|
+
*/
|
|
54
|
+
export interface ArticlePageProps extends Omit<PublicationLayoutProps, 'children'> {
|
|
55
|
+
/** Post component to render */
|
|
56
|
+
postComponent: React.ReactNode;
|
|
57
|
+
}
|
|
58
|
+
export declare function ArticlePage({ postComponent, ...layoutProps }: ArticlePageProps): Promise<React.JSX.Element>;
|
|
59
|
+
export interface CategoryPageProps extends PublicationLayoutProps {
|
|
60
|
+
/** Category slug being viewed */
|
|
61
|
+
category: string;
|
|
62
|
+
/** Category display name */
|
|
63
|
+
categoryName?: string;
|
|
64
|
+
/** List component */
|
|
65
|
+
listComponent: React.ReactNode;
|
|
66
|
+
}
|
|
67
|
+
export declare function CategoryPage({ category, categoryName, listComponent, hero, ...layoutProps }: CategoryPageProps): Promise<React.JSX.Element>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/press-kit/articles - Article Sidebar Component
|
|
3
|
+
*
|
|
4
|
+
* A reusable sidebar for article pages with categories, recent posts,
|
|
5
|
+
* tags, newsletter signup, and custom widgets.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import { type PublicationRoutingOptions } from './routes';
|
|
9
|
+
export interface PublicationSidebarProps {
|
|
10
|
+
/** Sonor API URL */
|
|
11
|
+
apiUrl?: string;
|
|
12
|
+
/** Project API key */
|
|
13
|
+
apiKey?: string;
|
|
14
|
+
/** Sub-site host for multi-site projects. Omit to resolve from NEXT_PUBLIC_SITE_URL. */
|
|
15
|
+
site?: string;
|
|
16
|
+
/** Show categories widget */
|
|
17
|
+
showCategories?: boolean;
|
|
18
|
+
/** Show recent posts widget */
|
|
19
|
+
showRecentPosts?: boolean;
|
|
20
|
+
/** Number of recent posts to show */
|
|
21
|
+
recentPostsCount?: number;
|
|
22
|
+
/** Show tags widget */
|
|
23
|
+
showTags?: boolean;
|
|
24
|
+
/** Show search widget */
|
|
25
|
+
showSearch?: boolean;
|
|
26
|
+
/** Base URL for article links */
|
|
27
|
+
basePath?: string;
|
|
28
|
+
routing?: PublicationRoutingOptions;
|
|
29
|
+
/** Custom class name */
|
|
30
|
+
className?: string;
|
|
31
|
+
/** Current category filter (for highlighting) */
|
|
32
|
+
currentCategory?: string;
|
|
33
|
+
/** Additional widgets to render */
|
|
34
|
+
children?: React.ReactNode;
|
|
35
|
+
}
|
|
36
|
+
export declare function PublicationSidebar({ apiUrl, apiKey, site, showCategories, showRecentPosts, recentPostsCount, showTags, showSearch, basePath, routing, className, currentCategory, children, }: PublicationSidebarProps): Promise<React.JSX.Element | null>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/press-kit/articles - Related articles component
|
|
3
|
+
*
|
|
4
|
+
* Fetches and displays related articles via Sonor API
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { Article } from './types';
|
|
8
|
+
import { type PublicationRoutingOptions } from './routes';
|
|
9
|
+
interface RelatedPostsServerProps {
|
|
10
|
+
apiUrl?: string;
|
|
11
|
+
apiKey?: string;
|
|
12
|
+
currentPostId: string;
|
|
13
|
+
limit?: number;
|
|
14
|
+
/** Sub-site host for multi-site projects. Omit to resolve from NEXT_PUBLIC_SITE_URL. */
|
|
15
|
+
site?: string;
|
|
16
|
+
className?: string;
|
|
17
|
+
basePath?: string;
|
|
18
|
+
routing?: PublicationRoutingOptions;
|
|
19
|
+
renderItem?: (post: Article) => React.ReactNode;
|
|
20
|
+
}
|
|
21
|
+
export declare function RelatedPosts({ apiUrl, apiKey, currentPostId, limit, site, className, basePath, routing, renderItem, }: RelatedPostsServerProps): Promise<React.JSX.Element | null>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/press-kit/articles - Service Callout / CTA Component
|
|
3
|
+
*
|
|
4
|
+
* Renders a promotional call-to-action section within articles.
|
|
5
|
+
* Automatically generated by Signal AI during article creation, linking
|
|
6
|
+
* article content to the business's relevant services.
|
|
7
|
+
*
|
|
8
|
+
* Two variants:
|
|
9
|
+
* - 'featured' (default): Full-width gradient banner with button
|
|
10
|
+
* - 'inline': Compact card with icon accent
|
|
11
|
+
*
|
|
12
|
+
* Uses site-kit brand tokens (--sk-primary, --sk-bg, etc.) for theming.
|
|
13
|
+
* Supports full Tailwind override via `styles` prop.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* <ServiceCallout
|
|
18
|
+
* title="Ready to build your MVP?"
|
|
19
|
+
* description="Our team specializes in lean SaaS builds."
|
|
20
|
+
* cta="Get Started"
|
|
21
|
+
* url="/services/application-development"
|
|
22
|
+
* />
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
import React from 'react';
|
|
26
|
+
export interface ServiceCalloutProps {
|
|
27
|
+
title: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
cta?: string;
|
|
30
|
+
url: string;
|
|
31
|
+
variant?: 'featured' | 'inline';
|
|
32
|
+
/** Override default styles with Tailwind classes */
|
|
33
|
+
styles?: {
|
|
34
|
+
wrapper?: string;
|
|
35
|
+
title?: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
button?: string;
|
|
38
|
+
};
|
|
39
|
+
/** Strip all default styles (BYO Tailwind) */
|
|
40
|
+
unstyled?: boolean;
|
|
41
|
+
}
|
|
42
|
+
export declare function ServiceCallout({ title, description, cta, url, variant, styles, unstyled, }: ServiceCalloutProps): React.JSX.Element;
|
|
43
|
+
/**
|
|
44
|
+
* Renders all service callouts for an article.
|
|
45
|
+
* First callout uses 'featured' variant, subsequent use 'inline'.
|
|
46
|
+
*/
|
|
47
|
+
export declare function ServiceCallouts({ callouts, styles, unstyled, }: {
|
|
48
|
+
callouts: Array<{
|
|
49
|
+
title: string;
|
|
50
|
+
description?: string;
|
|
51
|
+
cta?: string;
|
|
52
|
+
url: string;
|
|
53
|
+
}>;
|
|
54
|
+
styles?: ServiceCalloutProps['styles'];
|
|
55
|
+
unstyled?: boolean;
|
|
56
|
+
}): React.JSX.Element | null;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/press-kit/articles - Table of Contents Component
|
|
3
|
+
*/
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import type { TableOfContentsProps } from './types';
|
|
6
|
+
export declare function TableOfContents({ content, className, maxDepth, }: TableOfContentsProps): React.JSX.Element | null;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ArticleEditorialPhoto } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Inserts approved public photo snapshots at explicitly authored placements.
|
|
4
|
+
* Missing/duplicate headings, unmatched sections and photos already in the body
|
|
5
|
+
* are skipped. Never changes the author's paragraphs, headings or other markup.
|
|
6
|
+
* This is a layout transform, not a sanitizer for the original article HTML.
|
|
7
|
+
*/
|
|
8
|
+
export declare function insertArticlePhotos(html: string, photos?: ArticleEditorialPhoto[] | null): string;
|
|
9
|
+
export declare const articlePhotoCss = "\n.sk-article-photo { margin: 2em 0; max-width: 100%; }\n.sk-article-photo img { display: block; width: 100%; max-width: 100%; height: auto; border-radius: var(--sk-radius, 0.75rem); }\n.sk-article-photo figcaption { margin-top: 0.65em; color: var(--sk-text-secondary, inherit); font-size: 0.875em; line-height: 1.5; overflow-wrap: anywhere; }\n";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scoped CSS for Article and ArticleList default rendering.
|
|
3
|
+
*
|
|
4
|
+
* Injected via `<style>` in the server component output so consumers
|
|
5
|
+
* get a polished article with zero configuration.
|
|
6
|
+
*
|
|
7
|
+
* All colours use `--sk-*` CSS custom properties with `color-mix()` fallbacks
|
|
8
|
+
* that adapt to both light and dark host sites. The host can set:
|
|
9
|
+
*
|
|
10
|
+
* --sk-primary Brand accent (links, highlights)
|
|
11
|
+
* --sk-bg Page background
|
|
12
|
+
* --sk-bg-elevated Card / elevated surface background
|
|
13
|
+
* --sk-text-primary Main text
|
|
14
|
+
* --sk-text-secondary Subdued text
|
|
15
|
+
* --sk-text-tertiary Faint text / meta
|
|
16
|
+
* --sk-surface-border Subtle border color
|
|
17
|
+
*
|
|
18
|
+
* If none are set the defaults produce a clean neutral light-mode look.
|
|
19
|
+
*/
|
|
20
|
+
export declare const articleCss: string;
|
|
21
|
+
export declare const articleListCss: string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-rendered table scrolling. Keep the author's table markup intact so
|
|
3
|
+
* captions, header associations, links and table semantics survive unchanged.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Single source of truth for default article table wrappers. Safe to call twice;
|
|
7
|
+
* already wrapped tables and HTML examples are left alone. This is a layout
|
|
8
|
+
* transform, not an HTML sanitizer: content still follows the host's trust policy.
|
|
9
|
+
*/
|
|
10
|
+
export declare function wrapArticleTables(html: string): string;
|
|
11
|
+
/** Native overflow only when content needs it; small tables retain their layout. */
|
|
12
|
+
export declare const articleTableCss: string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CSSProperties } from 'react';
|
|
2
|
+
import type { Article } from './types';
|
|
3
|
+
export interface ArticleArtwork {
|
|
4
|
+
src: string | undefined;
|
|
5
|
+
alt: string;
|
|
6
|
+
composed: boolean;
|
|
7
|
+
}
|
|
8
|
+
type ArtworkSource = Pick<Article, 'title' | 'featured_image' | 'featured_image_alt' | 'editorial_image' | 'editorial_image_alt'>;
|
|
9
|
+
/** Single source of truth for article artwork versus complete promotional cards. */
|
|
10
|
+
export declare function resolveArticleArtwork(post: ArtworkSource, placement?: 'article' | 'card'): ArticleArtwork;
|
|
11
|
+
/** Preserve generated text and graphics across every stock card surface. */
|
|
12
|
+
export declare function articleArtworkImageStyle(artwork: ArticleArtwork): CSSProperties | undefined;
|
|
13
|
+
export {};
|