@highjumpdigitalsoftware/blog-kit 0.6.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/INTEGRATION.md +76 -0
- package/LICENSE +74 -0
- package/README.md +102 -0
- package/astro/AdPreview.astro +64 -0
- package/astro/AdPreviewPair.astro +10 -0
- package/astro/AuditFindings.astro +29 -0
- package/astro/AuditScores.astro +60 -0
- package/astro/AuthorCard.astro +32 -0
- package/astro/BeforeAfter.astro +26 -0
- package/astro/BlogBehaviors.astro +15 -0
- package/astro/CTABanner.astro +28 -0
- package/astro/CalloutBox.astro +28 -0
- package/astro/CaseStudyHero.astro +45 -0
- package/astro/ChannelMixBars.astro +33 -0
- package/astro/Checklist.astro +24 -0
- package/astro/ChecklistItem.astro +15 -0
- package/astro/CodeSnippet.astro +20 -0
- package/astro/ComparisonTable.astro +103 -0
- package/astro/Definition.astro +30 -0
- package/astro/DeliveryComparison.astro +40 -0
- package/astro/FAQList.astro +43 -0
- package/astro/FurtherReading.astro +34 -0
- package/astro/ImageFeature.astro +22 -0
- package/astro/Infographic.astro +12 -0
- package/astro/KeyMetric.astro +40 -0
- package/astro/KeywordTable.astro +69 -0
- package/astro/List.astro +46 -0
- package/astro/MetricHighlight.astro +77 -0
- package/astro/NewsletterCTA.astro +40 -0
- package/astro/NumberedCard.astro +6 -0
- package/astro/ProConBlock.astro +38 -0
- package/astro/ProseList.astro +46 -0
- package/astro/QuoteBlock.astro +72 -0
- package/astro/RegionCallout.astro +24 -0
- package/astro/RelatedPosts.astro +47 -0
- package/astro/ResultsStrip.astro +59 -0
- package/astro/ScoreBar.astro +19 -0
- package/astro/SerpPreview.astro +35 -0
- package/astro/ServicePromoCard.astro +21 -0
- package/astro/StatCard.astro +48 -0
- package/astro/StepBlock.astro +5 -0
- package/astro/TableOfContents.astro +12 -0
- package/astro/TimelineBlock.astro +30 -0
- package/astro/TipBox.astro +14 -0
- package/astro/TrafficChart.astro +61 -0
- package/astro/VerdictCard.astro +48 -0
- package/astro/blogkit/Article.astro +63 -0
- package/astro/blogkit/BlogIndex.astro +144 -0
- package/core/behaviors/code.js +78 -0
- package/core/behaviors/comparison.js +52 -0
- package/core/behaviors/delivery-comparison.js +52 -0
- package/core/behaviors/faq.js +61 -0
- package/core/behaviors/index.d.ts +3 -0
- package/core/behaviors/index.js +35 -0
- package/core/behaviors/keyword-table.js +52 -0
- package/core/behaviors/toc.js +130 -0
- package/core/css/base.css +146 -0
- package/core/css/components.css +2632 -0
- package/core/css/index-listing.css +207 -0
- package/core/css/index.css +13 -0
- package/core/css/tokens.css +127 -0
- package/core/icons.ts +20 -0
- package/core/lib.ts +70 -0
- package/core/manifest/components.json +573 -0
- package/core/manifest/frontmatter.json +19 -0
- package/core/manifest/templates.json +77 -0
- package/dist/core/behaviors/code.js +78 -0
- package/dist/core/behaviors/comparison.js +52 -0
- package/dist/core/behaviors/delivery-comparison.js +52 -0
- package/dist/core/behaviors/faq.js +61 -0
- package/dist/core/behaviors/index.d.ts +3 -0
- package/dist/core/behaviors/index.js +35 -0
- package/dist/core/behaviors/keyword-table.js +52 -0
- package/dist/core/behaviors/toc.js +130 -0
- package/dist/core/css/base.css +146 -0
- package/dist/core/css/components.css +2632 -0
- package/dist/core/css/index-listing.css +207 -0
- package/dist/core/css/index.css +13 -0
- package/dist/core/css/tokens.css +127 -0
- package/dist/core/icons.d.ts +2 -0
- package/dist/core/icons.d.ts.map +1 -0
- package/dist/core/icons.js +20 -0
- package/dist/core/icons.js.map +1 -0
- package/dist/core/lib.d.ts +21 -0
- package/dist/core/lib.d.ts.map +1 -0
- package/dist/core/lib.js +57 -0
- package/dist/core/lib.js.map +1 -0
- package/dist/core/manifest/components.json +573 -0
- package/dist/core/manifest/frontmatter.json +19 -0
- package/dist/core/manifest/templates.json +77 -0
- package/dist/package/adapters/hjd-api.d.ts +14 -0
- package/dist/package/adapters/hjd-api.d.ts.map +1 -0
- package/dist/package/adapters/hjd-api.js +57 -0
- package/dist/package/adapters/hjd-api.js.map +1 -0
- package/dist/package/adapters/index.d.ts +13 -0
- package/dist/package/adapters/index.d.ts.map +1 -0
- package/dist/package/adapters/index.js +16 -0
- package/dist/package/adapters/index.js.map +1 -0
- package/dist/package/adapters/local.d.ts +13 -0
- package/dist/package/adapters/local.d.ts.map +1 -0
- package/dist/package/adapters/local.js +72 -0
- package/dist/package/adapters/local.js.map +1 -0
- package/dist/package/adapters/source.d.ts +39 -0
- package/dist/package/adapters/source.d.ts.map +1 -0
- package/dist/package/adapters/source.js +19 -0
- package/dist/package/adapters/source.js.map +1 -0
- package/dist/package/article.d.ts +17 -0
- package/dist/package/article.d.ts.map +1 -0
- package/dist/package/article.js +37 -0
- package/dist/package/article.js.map +1 -0
- package/dist/package/astro/data.d.ts +45 -0
- package/dist/package/astro/data.d.ts.map +1 -0
- package/dist/package/astro/data.js +81 -0
- package/dist/package/astro/data.js.map +1 -0
- package/dist/package/astro/freshness.d.ts +11 -0
- package/dist/package/astro/freshness.d.ts.map +1 -0
- package/dist/package/astro/freshness.js +48 -0
- package/dist/package/astro/freshness.js.map +1 -0
- package/dist/package/astro/index.d.ts +12 -0
- package/dist/package/astro/index.d.ts.map +1 -0
- package/dist/package/astro/index.js +31 -0
- package/dist/package/astro/index.js.map +1 -0
- package/dist/package/blog-index.d.ts +10 -0
- package/dist/package/blog-index.d.ts.map +1 -0
- package/dist/package/blog-index.js +27 -0
- package/dist/package/blog-index.js.map +1 -0
- package/dist/package/cli/exchange.d.ts +27 -0
- package/dist/package/cli/exchange.d.ts.map +1 -0
- package/dist/package/cli/exchange.js +94 -0
- package/dist/package/cli/exchange.js.map +1 -0
- package/dist/package/cli/index.d.ts +3 -0
- package/dist/package/cli/index.d.ts.map +1 -0
- package/dist/package/cli/index.js +301 -0
- package/dist/package/cli/index.js.map +1 -0
- package/dist/package/config/define.d.ts +13 -0
- package/dist/package/config/define.d.ts.map +1 -0
- package/dist/package/config/define.js +14 -0
- package/dist/package/config/define.js.map +1 -0
- package/dist/package/config/resolve.d.ts +11 -0
- package/dist/package/config/resolve.d.ts.map +1 -0
- package/dist/package/config/resolve.js +43 -0
- package/dist/package/config/resolve.js.map +1 -0
- package/dist/package/config/types.d.ts +74 -0
- package/dist/package/config/types.d.ts.map +1 -0
- package/dist/package/config/types.js +13 -0
- package/dist/package/config/types.js.map +1 -0
- package/dist/package/index-core.d.ts +28 -0
- package/dist/package/index-core.d.ts.map +1 -0
- package/dist/package/index-core.js +102 -0
- package/dist/package/index-core.js.map +1 -0
- package/dist/package/index.d.ts +13 -0
- package/dist/package/index.d.ts.map +1 -0
- package/dist/package/index.js +25 -0
- package/dist/package/index.js.map +1 -0
- package/dist/package/mdx/render-astro.d.ts +18 -0
- package/dist/package/mdx/render-astro.d.ts.map +1 -0
- package/dist/package/mdx/render-astro.js +75 -0
- package/dist/package/mdx/render-astro.js.map +1 -0
- package/dist/package/mdx/render.d.ts +13 -0
- package/dist/package/mdx/render.d.ts.map +1 -0
- package/dist/package/mdx/render.js +37 -0
- package/dist/package/mdx/render.js.map +1 -0
- package/dist/react/AdPreview.d.ts +26 -0
- package/dist/react/AdPreview.d.ts.map +1 -0
- package/dist/react/AdPreview.js +8 -0
- package/dist/react/AdPreview.js.map +1 -0
- package/dist/react/AdPreviewPair.d.ts +7 -0
- package/dist/react/AdPreviewPair.d.ts.map +1 -0
- package/dist/react/AdPreviewPair.js +5 -0
- package/dist/react/AdPreviewPair.js.map +1 -0
- package/dist/react/AuditFindings.d.ts +14 -0
- package/dist/react/AuditFindings.d.ts.map +1 -0
- package/dist/react/AuditFindings.js +5 -0
- package/dist/react/AuditFindings.js.map +1 -0
- package/dist/react/AuditScores.d.ts +12 -0
- package/dist/react/AuditScores.d.ts.map +1 -0
- package/dist/react/AuditScores.js +25 -0
- package/dist/react/AuditScores.js.map +1 -0
- package/dist/react/AuthorCard.d.ts +10 -0
- package/dist/react/AuthorCard.d.ts.map +1 -0
- package/dist/react/AuthorCard.js +6 -0
- package/dist/react/AuthorCard.js.map +1 -0
- package/dist/react/BeforeAfter.d.ts +12 -0
- package/dist/react/BeforeAfter.d.ts.map +1 -0
- package/dist/react/BeforeAfter.js +7 -0
- package/dist/react/BeforeAfter.js.map +1 -0
- package/dist/react/BlogBehaviors.d.ts +10 -0
- package/dist/react/BlogBehaviors.d.ts.map +1 -0
- package/dist/react/BlogBehaviors.js +20 -0
- package/dist/react/BlogBehaviors.js.map +1 -0
- package/dist/react/CTABanner.d.ts +8 -0
- package/dist/react/CTABanner.d.ts.map +1 -0
- package/dist/react/CTABanner.js +9 -0
- package/dist/react/CTABanner.js.map +1 -0
- package/dist/react/CalloutBox.d.ts +13 -0
- package/dist/react/CalloutBox.d.ts.map +1 -0
- package/dist/react/CalloutBox.js +9 -0
- package/dist/react/CalloutBox.js.map +1 -0
- package/dist/react/CaseStudyHero.d.ts +20 -0
- package/dist/react/CaseStudyHero.d.ts.map +1 -0
- package/dist/react/CaseStudyHero.js +7 -0
- package/dist/react/CaseStudyHero.js.map +1 -0
- package/dist/react/ChannelMixBars.d.ts +18 -0
- package/dist/react/ChannelMixBars.d.ts.map +1 -0
- package/dist/react/ChannelMixBars.js +6 -0
- package/dist/react/ChannelMixBars.js.map +1 -0
- package/dist/react/Checklist.d.ts +10 -0
- package/dist/react/Checklist.d.ts.map +1 -0
- package/dist/react/Checklist.js +7 -0
- package/dist/react/Checklist.js.map +1 -0
- package/dist/react/ChecklistItem.d.ts +7 -0
- package/dist/react/ChecklistItem.d.ts.map +1 -0
- package/dist/react/ChecklistItem.js +5 -0
- package/dist/react/ChecklistItem.js.map +1 -0
- package/dist/react/CodeSnippet.d.ts +17 -0
- package/dist/react/CodeSnippet.d.ts.map +1 -0
- package/dist/react/CodeSnippet.js +14 -0
- package/dist/react/CodeSnippet.js.map +1 -0
- package/dist/react/ComparisonTable.d.ts +22 -0
- package/dist/react/ComparisonTable.d.ts.map +1 -0
- package/dist/react/ComparisonTable.js +35 -0
- package/dist/react/ComparisonTable.js.map +1 -0
- package/dist/react/Definition.d.ts +9 -0
- package/dist/react/Definition.d.ts.map +1 -0
- package/dist/react/Definition.js +19 -0
- package/dist/react/Definition.js.map +1 -0
- package/dist/react/DeliveryComparison.d.ts +16 -0
- package/dist/react/DeliveryComparison.d.ts.map +1 -0
- package/dist/react/DeliveryComparison.js +7 -0
- package/dist/react/DeliveryComparison.js.map +1 -0
- package/dist/react/FAQList.d.ts +20 -0
- package/dist/react/FAQList.d.ts.map +1 -0
- package/dist/react/FAQList.js +19 -0
- package/dist/react/FAQList.js.map +1 -0
- package/dist/react/FurtherReading.d.ts +21 -0
- package/dist/react/FurtherReading.d.ts.map +1 -0
- package/dist/react/FurtherReading.js +13 -0
- package/dist/react/FurtherReading.js.map +1 -0
- package/dist/react/ImageFeature.d.ts +9 -0
- package/dist/react/ImageFeature.d.ts.map +1 -0
- package/dist/react/ImageFeature.js +6 -0
- package/dist/react/ImageFeature.js.map +1 -0
- package/dist/react/Infographic.d.ts +6 -0
- package/dist/react/Infographic.d.ts.map +1 -0
- package/dist/react/Infographic.js +7 -0
- package/dist/react/Infographic.js.map +1 -0
- package/dist/react/KeyMetric.d.ts +16 -0
- package/dist/react/KeyMetric.d.ts.map +1 -0
- package/dist/react/KeyMetric.js +15 -0
- package/dist/react/KeyMetric.js.map +1 -0
- package/dist/react/KeywordTable.d.ts +18 -0
- package/dist/react/KeywordTable.d.ts.map +1 -0
- package/dist/react/KeywordTable.js +23 -0
- package/dist/react/KeywordTable.js.map +1 -0
- package/dist/react/List.d.ts +11 -0
- package/dist/react/List.d.ts.map +1 -0
- package/dist/react/List.js +21 -0
- package/dist/react/List.js.map +1 -0
- package/dist/react/MetricHighlight.d.ts +15 -0
- package/dist/react/MetricHighlight.d.ts.map +1 -0
- package/dist/react/MetricHighlight.js +26 -0
- package/dist/react/MetricHighlight.js.map +1 -0
- package/dist/react/NewsletterCTA.d.ts +9 -0
- package/dist/react/NewsletterCTA.d.ts.map +1 -0
- package/dist/react/NewsletterCTA.js +5 -0
- package/dist/react/NewsletterCTA.js.map +1 -0
- package/dist/react/NumberedCard.d.ts +9 -0
- package/dist/react/NumberedCard.d.ts.map +1 -0
- package/dist/react/NumberedCard.js +7 -0
- package/dist/react/NumberedCard.js.map +1 -0
- package/dist/react/ProConBlock.d.ts +6 -0
- package/dist/react/ProConBlock.d.ts.map +1 -0
- package/dist/react/ProConBlock.js +7 -0
- package/dist/react/ProConBlock.js.map +1 -0
- package/dist/react/ProseList.d.ts +17 -0
- package/dist/react/ProseList.d.ts.map +1 -0
- package/dist/react/ProseList.js +26 -0
- package/dist/react/ProseList.js.map +1 -0
- package/dist/react/QuoteBlock.d.ts +17 -0
- package/dist/react/QuoteBlock.d.ts.map +1 -0
- package/dist/react/QuoteBlock.js +26 -0
- package/dist/react/QuoteBlock.js.map +1 -0
- package/dist/react/RegionCallout.d.ts +13 -0
- package/dist/react/RegionCallout.d.ts.map +1 -0
- package/dist/react/RegionCallout.js +5 -0
- package/dist/react/RegionCallout.js.map +1 -0
- package/dist/react/RelatedPosts.d.ts +20 -0
- package/dist/react/RelatedPosts.d.ts.map +1 -0
- package/dist/react/RelatedPosts.js +7 -0
- package/dist/react/RelatedPosts.js.map +1 -0
- package/dist/react/ResultsStrip.d.ts +18 -0
- package/dist/react/ResultsStrip.d.ts.map +1 -0
- package/dist/react/ResultsStrip.js +22 -0
- package/dist/react/ResultsStrip.js.map +1 -0
- package/dist/react/ScoreBar.d.ts +8 -0
- package/dist/react/ScoreBar.d.ts.map +1 -0
- package/dist/react/ScoreBar.js +6 -0
- package/dist/react/ScoreBar.js.map +1 -0
- package/dist/react/SerpPreview.d.ts +18 -0
- package/dist/react/SerpPreview.d.ts.map +1 -0
- package/dist/react/SerpPreview.js +13 -0
- package/dist/react/SerpPreview.js.map +1 -0
- package/dist/react/ServicePromoCard.d.ts +14 -0
- package/dist/react/ServicePromoCard.d.ts.map +1 -0
- package/dist/react/ServicePromoCard.js +12 -0
- package/dist/react/ServicePromoCard.js.map +1 -0
- package/dist/react/StatCard.d.ts +13 -0
- package/dist/react/StatCard.d.ts.map +1 -0
- package/dist/react/StatCard.js +20 -0
- package/dist/react/StatCard.js.map +1 -0
- package/dist/react/StepBlock.d.ts +8 -0
- package/dist/react/StepBlock.d.ts.map +1 -0
- package/dist/react/StepBlock.js +5 -0
- package/dist/react/StepBlock.js.map +1 -0
- package/dist/react/TableOfContents.d.ts +14 -0
- package/dist/react/TableOfContents.d.ts.map +1 -0
- package/dist/react/TableOfContents.js +12 -0
- package/dist/react/TableOfContents.js.map +1 -0
- package/dist/react/TimelineBlock.d.ts +14 -0
- package/dist/react/TimelineBlock.d.ts.map +1 -0
- package/dist/react/TimelineBlock.js +8 -0
- package/dist/react/TimelineBlock.js.map +1 -0
- package/dist/react/TipBox.d.ts +6 -0
- package/dist/react/TipBox.d.ts.map +1 -0
- package/dist/react/TipBox.js +5 -0
- package/dist/react/TipBox.js.map +1 -0
- package/dist/react/TrafficChart.d.ts +16 -0
- package/dist/react/TrafficChart.d.ts.map +1 -0
- package/dist/react/TrafficChart.js +14 -0
- package/dist/react/TrafficChart.js.map +1 -0
- package/dist/react/VerdictCard.d.ts +15 -0
- package/dist/react/VerdictCard.d.ts.map +1 -0
- package/dist/react/VerdictCard.js +5 -0
- package/dist/react/VerdictCard.js.map +1 -0
- package/dist/react/components-map.d.ts +133 -0
- package/dist/react/components-map.d.ts.map +1 -0
- package/dist/react/components-map.js +120 -0
- package/dist/react/components-map.js.map +1 -0
- package/dist/react/index.d.ts +5 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +13 -0
- package/dist/react/index.js.map +1 -0
- package/package.json +116 -0
- package/react/AdPreview.tsx +94 -0
- package/react/AdPreviewPair.tsx +16 -0
- package/react/AuditFindings.tsx +43 -0
- package/react/AuditScores.tsx +73 -0
- package/react/AuthorCard.tsx +35 -0
- package/react/BeforeAfter.tsx +27 -0
- package/react/BlogBehaviors.tsx +21 -0
- package/react/CTABanner.tsx +32 -0
- package/react/CalloutBox.tsx +31 -0
- package/react/CaseStudyHero.tsx +71 -0
- package/react/ChannelMixBars.tsx +50 -0
- package/react/Checklist.tsx +31 -0
- package/react/ChecklistItem.tsx +19 -0
- package/react/CodeSnippet.tsx +36 -0
- package/react/ComparisonTable.tsx +114 -0
- package/react/Definition.tsx +36 -0
- package/react/DeliveryComparison.tsx +62 -0
- package/react/FAQList.tsx +61 -0
- package/react/FurtherReading.tsx +46 -0
- package/react/ImageFeature.tsx +26 -0
- package/react/Infographic.tsx +18 -0
- package/react/KeyMetric.tsx +61 -0
- package/react/KeywordTable.tsx +92 -0
- package/react/List.tsx +58 -0
- package/react/MetricHighlight.tsx +86 -0
- package/react/NewsletterCTA.tsx +48 -0
- package/react/NumberedCard.tsx +7 -0
- package/react/ProConBlock.tsx +42 -0
- package/react/ProseList.tsx +72 -0
- package/react/QuoteBlock.tsx +89 -0
- package/react/RegionCallout.tsx +38 -0
- package/react/RelatedPosts.tsx +58 -0
- package/react/ResultsStrip.tsx +77 -0
- package/react/ScoreBar.tsx +27 -0
- package/react/SerpPreview.tsx +59 -0
- package/react/ServicePromoCard.tsx +43 -0
- package/react/StatCard.tsx +62 -0
- package/react/StepBlock.tsx +5 -0
- package/react/TableOfContents.tsx +27 -0
- package/react/TimelineBlock.tsx +35 -0
- package/react/TipBox.tsx +16 -0
- package/react/TrafficChart.tsx +79 -0
- package/react/VerdictCard.tsx +60 -0
- package/react/components-map.ts +122 -0
- package/react/index.ts +13 -0
- package/templates/blogkit/app/api/blogkit/revalidate/route.ts.tmpl +32 -0
- package/templates/blogkit/app/blog/[slug]/page.tsx.tmpl +41 -0
- package/templates/blogkit/app/blog/page.tsx.tmpl +18 -0
- package/templates/blogkit/blogkit.config.ts.tmpl +23 -0
- package/templates/blogkit-astro/BLOGKIT_ASTRO_SETUP.md.tmpl +49 -0
- package/templates/blogkit-astro/src/blogkit.config.ts.tmpl +29 -0
- package/templates/blogkit-astro/src/pages/api/blogkit/revalidate.ts.tmpl +46 -0
- package/templates/blogkit-astro/src/pages/blog/[slug].astro.tmpl +39 -0
- package/templates/blogkit-astro/src/pages/blog/index.astro.tmpl +29 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
blog-kit React component MAPS — Next-free.
|
|
3
|
+
------------------------------------------------------------
|
|
4
|
+
The presentational React components are framework-neutral, but
|
|
5
|
+
the sibling `react/index.ts` barrel ALSO re-exports
|
|
6
|
+
<BlogBehaviors>, which imports `next/navigation`. Evaluating that
|
|
7
|
+
barrel therefore pulls Next, so it cannot be imported under raw
|
|
8
|
+
Node / Astro SSR (no Next).
|
|
9
|
+
|
|
10
|
+
This module re-exports ONLY the component MAPS (no BlogBehaviors),
|
|
11
|
+
so the runtime-MDX render path (Next OR Astro) can import the map
|
|
12
|
+
without dragging Next in. `react/index.ts` re-exports these maps so
|
|
13
|
+
the maps stay single-source — edit the imports here, not in two
|
|
14
|
+
places.
|
|
15
|
+
============================================================ */
|
|
16
|
+
import { AdPreview } from "./AdPreview.js";
|
|
17
|
+
import { AdPreviewPair } from "./AdPreviewPair.js";
|
|
18
|
+
import { AuditFindings } from "./AuditFindings.js";
|
|
19
|
+
import { AuditScores } from "./AuditScores.js";
|
|
20
|
+
import { AuthorCard } from "./AuthorCard.js";
|
|
21
|
+
import { BeforeAfter } from "./BeforeAfter.js";
|
|
22
|
+
import { CTABanner } from "./CTABanner.js";
|
|
23
|
+
import { CalloutBox } from "./CalloutBox.js";
|
|
24
|
+
import { CaseStudyHero } from "./CaseStudyHero.js";
|
|
25
|
+
import { ChannelMixBars } from "./ChannelMixBars.js";
|
|
26
|
+
import { Checklist } from "./Checklist.js";
|
|
27
|
+
import { ChecklistItem } from "./ChecklistItem.js";
|
|
28
|
+
import { CodeSnippet } from "./CodeSnippet.js";
|
|
29
|
+
import { ComparisonTable } from "./ComparisonTable.js";
|
|
30
|
+
import { Definition } from "./Definition.js";
|
|
31
|
+
import { DeliveryComparison } from "./DeliveryComparison.js";
|
|
32
|
+
import { FAQList } from "./FAQList.js";
|
|
33
|
+
import { FurtherReading } from "./FurtherReading.js";
|
|
34
|
+
import { ImageFeature } from "./ImageFeature.js";
|
|
35
|
+
import { Infographic } from "./Infographic.js";
|
|
36
|
+
import { KeyMetric } from "./KeyMetric.js";
|
|
37
|
+
import { KeywordTable } from "./KeywordTable.js";
|
|
38
|
+
import { List } from "./List.js";
|
|
39
|
+
import { MetricHighlight } from "./MetricHighlight.js";
|
|
40
|
+
import { NewsletterCTA } from "./NewsletterCTA.js";
|
|
41
|
+
import { NumberedCard } from "./NumberedCard.js";
|
|
42
|
+
import { ProConBlock } from "./ProConBlock.js";
|
|
43
|
+
import { ProseList } from "./ProseList.js";
|
|
44
|
+
import { QuoteBlock } from "./QuoteBlock.js";
|
|
45
|
+
import { RegionCallout } from "./RegionCallout.js";
|
|
46
|
+
import { RelatedPosts } from "./RelatedPosts.js";
|
|
47
|
+
import { ResultsStrip } from "./ResultsStrip.js";
|
|
48
|
+
import { ScoreBar } from "./ScoreBar.js";
|
|
49
|
+
import { SerpPreview } from "./SerpPreview.js";
|
|
50
|
+
import { ServicePromoCard } from "./ServicePromoCard.js";
|
|
51
|
+
import { StatCard } from "./StatCard.js";
|
|
52
|
+
import { StepBlock } from "./StepBlock.js";
|
|
53
|
+
import { TableOfContents } from "./TableOfContents.js";
|
|
54
|
+
import { TimelineBlock } from "./TimelineBlock.js";
|
|
55
|
+
import { TipBox } from "./TipBox.js";
|
|
56
|
+
import { TrafficChart } from "./TrafficChart.js";
|
|
57
|
+
import { VerdictCard } from "./VerdictCard.js";
|
|
58
|
+
export const kitComponents = {
|
|
59
|
+
AdPreview,
|
|
60
|
+
AdPreviewPair,
|
|
61
|
+
AuditFindings,
|
|
62
|
+
AuditScores,
|
|
63
|
+
AuthorCard,
|
|
64
|
+
BeforeAfter,
|
|
65
|
+
CTABanner,
|
|
66
|
+
CalloutBox,
|
|
67
|
+
CaseStudyHero,
|
|
68
|
+
ChannelMixBars,
|
|
69
|
+
Checklist,
|
|
70
|
+
ChecklistItem,
|
|
71
|
+
CodeSnippet,
|
|
72
|
+
ComparisonTable,
|
|
73
|
+
Definition,
|
|
74
|
+
DeliveryComparison,
|
|
75
|
+
FAQList,
|
|
76
|
+
FurtherReading,
|
|
77
|
+
ImageFeature,
|
|
78
|
+
Infographic,
|
|
79
|
+
KeyMetric,
|
|
80
|
+
KeywordTable,
|
|
81
|
+
List,
|
|
82
|
+
MetricHighlight,
|
|
83
|
+
NewsletterCTA,
|
|
84
|
+
NumberedCard,
|
|
85
|
+
ProConBlock,
|
|
86
|
+
ProseList,
|
|
87
|
+
QuoteBlock,
|
|
88
|
+
RegionCallout,
|
|
89
|
+
RelatedPosts,
|
|
90
|
+
ResultsStrip,
|
|
91
|
+
ScoreBar,
|
|
92
|
+
SerpPreview,
|
|
93
|
+
ServicePromoCard,
|
|
94
|
+
StatCard,
|
|
95
|
+
StepBlock,
|
|
96
|
+
TableOfContents,
|
|
97
|
+
TimelineBlock,
|
|
98
|
+
TipBox,
|
|
99
|
+
TrafficChart,
|
|
100
|
+
VerdictCard,
|
|
101
|
+
};
|
|
102
|
+
/** Old MDX names kept renderable during migration → canonical component. */
|
|
103
|
+
export const aliasComponents = {
|
|
104
|
+
AuditTable: AuditFindings,
|
|
105
|
+
CaseStudy: CaseStudyHero,
|
|
106
|
+
CaseStudyBanner: CaseStudyHero,
|
|
107
|
+
FindingsList: AuditFindings,
|
|
108
|
+
GoogleResult: SerpPreview,
|
|
109
|
+
IssueList: AuditFindings,
|
|
110
|
+
LineChart: TrafficChart,
|
|
111
|
+
OfficeGrid: RegionCallout,
|
|
112
|
+
ProsCons: ProConBlock,
|
|
113
|
+
PullQuote: QuoteBlock,
|
|
114
|
+
RegionContacts: RegionCallout,
|
|
115
|
+
SearchPreview: SerpPreview,
|
|
116
|
+
TimelineRecap: TimelineBlock,
|
|
117
|
+
TrendChart: TrafficChart,
|
|
118
|
+
};
|
|
119
|
+
export const blogComponents = { ...kitComponents, ...aliasComponents };
|
|
120
|
+
//# sourceMappingURL=components-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components-map.js","sourceRoot":"","sources":["../../react/components-map.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { kitComponents, aliasComponents, blogComponents } from "./components-map";
|
|
2
|
+
/** Client-side activator for interactive components — render once inside
|
|
3
|
+
the post route's `.blog-root`. See react/BlogBehaviors.tsx. */
|
|
4
|
+
export { BlogBehaviors } from "./BlogBehaviors";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../react/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElF;kEACkE;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/* blog-kit React adapter — barrel (generated by assembler).
|
|
2
|
+
blogComponents is the map passed to <MDXRemote components={...} />.
|
|
3
|
+
Per-site custom components merge on top in the site's /blog route.
|
|
4
|
+
|
|
5
|
+
The component MAPS now live in ./components-map (Next-free) so the
|
|
6
|
+
Astro runtime-MDX render path can import the map WITHOUT pulling
|
|
7
|
+
<BlogBehaviors> (which imports next/navigation). This barrel keeps
|
|
8
|
+
its full public surface — maps + BlogBehaviors — for the Next path. */
|
|
9
|
+
export { kitComponents, aliasComponents, blogComponents } from "./components-map.js";
|
|
10
|
+
/** Client-side activator for interactive components — render once inside
|
|
11
|
+
the post route's `.blog-root`. See react/BlogBehaviors.tsx. */
|
|
12
|
+
export { BlogBehaviors } from "./BlogBehaviors.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;yEAOyE;AACzE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElF;kEACkE;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@highjumpdigitalsoftware/blog-kit",
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Canonical, framework-agnostic blog component kit. One shared core (CSS tokens + .bk-* styles + manifest + behaviours) consumed by thin React (Next.js) and Astro adapters. The blog-publisher MCP reads core/manifest as its single source of truth, and sites can vendor core/ + an adapter at build time. It ALSO ships as an installable package with a first-class managed path on BOTH Next.js and Astro: a swappable content-source adapter (local files or our hosted content API), /blog + /blog/[slug] route surfaces (Next ISR or Astro SSR with request-time MDX compile), an optional revalidate route, and a framework-aware connect/init CLI.",
|
|
6
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
7
|
+
"sideEffects": [
|
|
8
|
+
"*.css"
|
|
9
|
+
],
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"core",
|
|
13
|
+
"react",
|
|
14
|
+
"astro",
|
|
15
|
+
"templates/blogkit",
|
|
16
|
+
"templates/blogkit-astro",
|
|
17
|
+
"README.md",
|
|
18
|
+
"INTEGRATION.md"
|
|
19
|
+
],
|
|
20
|
+
"bin": {
|
|
21
|
+
"blog-kit": "dist/package/cli/index.js"
|
|
22
|
+
},
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/package/index.d.ts",
|
|
26
|
+
"import": "./dist/package/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./astro": {
|
|
29
|
+
"types": "./dist/package/astro/index.d.ts",
|
|
30
|
+
"import": "./dist/package/astro/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./astro/Article.astro": "./astro/blogkit/Article.astro",
|
|
33
|
+
"./astro/BlogIndex.astro": "./astro/blogkit/BlogIndex.astro",
|
|
34
|
+
"./astro/*": "./astro/*",
|
|
35
|
+
"./styles.css": "./dist/core/css/index.css",
|
|
36
|
+
"./components": {
|
|
37
|
+
"types": "./dist/react/index.d.ts",
|
|
38
|
+
"import": "./dist/react/index.js"
|
|
39
|
+
},
|
|
40
|
+
"./package.json": "./package.json"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"demo": "echo 'Open demo/index.html in a browser to preview components across themes.'",
|
|
44
|
+
"build": "tsc -p tsconfig.package.json && node scripts/pkg-copy-assets.mjs",
|
|
45
|
+
"clean": "rm -rf dist",
|
|
46
|
+
"prepack": "npm run clean && npm run build",
|
|
47
|
+
"selfcheck": "node scripts/pkg-selfcheck.mjs",
|
|
48
|
+
"validate-index": "node scripts/validate-blog-index.mjs"
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=18.18.0"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"gray-matter": "^4.0.3",
|
|
55
|
+
"reading-time": "^1.5.0"
|
|
56
|
+
},
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"@mdx-js/mdx": "^3",
|
|
59
|
+
"astro": ">=5",
|
|
60
|
+
"next": ">=14",
|
|
61
|
+
"next-mdx-remote": "^6.0.0",
|
|
62
|
+
"react": ">=18",
|
|
63
|
+
"react-dom": ">=18",
|
|
64
|
+
"rehype-autolink-headings": "^7",
|
|
65
|
+
"rehype-pretty-code": ">=0.13",
|
|
66
|
+
"rehype-slug": "^6",
|
|
67
|
+
"remark-gfm": "^4"
|
|
68
|
+
},
|
|
69
|
+
"peerDependenciesMeta": {
|
|
70
|
+
"@mdx-js/mdx": {
|
|
71
|
+
"optional": true
|
|
72
|
+
},
|
|
73
|
+
"astro": {
|
|
74
|
+
"optional": true
|
|
75
|
+
},
|
|
76
|
+
"next": {
|
|
77
|
+
"optional": true
|
|
78
|
+
},
|
|
79
|
+
"next-mdx-remote": {
|
|
80
|
+
"optional": true
|
|
81
|
+
},
|
|
82
|
+
"react": {
|
|
83
|
+
"optional": true
|
|
84
|
+
},
|
|
85
|
+
"react-dom": {
|
|
86
|
+
"optional": true
|
|
87
|
+
},
|
|
88
|
+
"rehype-autolink-headings": {
|
|
89
|
+
"optional": true
|
|
90
|
+
},
|
|
91
|
+
"rehype-pretty-code": {
|
|
92
|
+
"optional": true
|
|
93
|
+
},
|
|
94
|
+
"rehype-slug": {
|
|
95
|
+
"optional": true
|
|
96
|
+
},
|
|
97
|
+
"remark-gfm": {
|
|
98
|
+
"optional": true
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"devDependencies": {
|
|
102
|
+
"@mdx-js/mdx": "^3.1.1",
|
|
103
|
+
"@types/node": "^22.15.2",
|
|
104
|
+
"@types/react": "^18.3.0",
|
|
105
|
+
"@types/react-dom": "^18.3.0",
|
|
106
|
+
"next": "^15.5.19",
|
|
107
|
+
"next-mdx-remote": "^6.0.0",
|
|
108
|
+
"react": "^18.3.0",
|
|
109
|
+
"react-dom": "^18.3.0",
|
|
110
|
+
"rehype-autolink-headings": "^7.1.0",
|
|
111
|
+
"rehype-pretty-code": "^0.14.3",
|
|
112
|
+
"rehype-slug": "^6.0.0",
|
|
113
|
+
"remark-gfm": "^4.0.1",
|
|
114
|
+
"typescript": "^5.8.3"
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/* blog-kit React adapter — AdPreview
|
|
2
|
+
Thin wrapper: all styling lives in core/css/components.css (.bk-ad-preview).
|
|
3
|
+
A mock paid-ad creative in one of two platform styles:
|
|
4
|
+
- "meta": a social feed ad — round brand avatar + "Sponsored" line, body
|
|
5
|
+
copy, a 1.91:1 media panel, and a footer with the site + a CTA button.
|
|
6
|
+
- "google": a search ad — an "Ad" pill, the display URL, a blue headline,
|
|
7
|
+
a description, and optional sitelinks.
|
|
8
|
+
Ported from hjd's b-ad (cyan/dark mapped to neutral --blog-* tokens; the
|
|
9
|
+
Google link-blue maps to --blog-info, matching SerpPreview). */
|
|
10
|
+
|
|
11
|
+
export interface AdPreviewProps {
|
|
12
|
+
/** Which ad style to render. Defaults to "meta". */
|
|
13
|
+
platform?: "meta" | "google";
|
|
14
|
+
|
|
15
|
+
/* ── meta props ── */
|
|
16
|
+
/** Advertiser name; its first two letters seed the round avatar. */
|
|
17
|
+
brand?: string;
|
|
18
|
+
/** Small label under the brand name. Defaults to "Sponsored". */
|
|
19
|
+
sponsored?: string;
|
|
20
|
+
/** Ad body copy. HTML allowed (e.g. <strong>, <br/>). */
|
|
21
|
+
copy?: string;
|
|
22
|
+
/** Optional creative image URL for the media panel. */
|
|
23
|
+
image?: string;
|
|
24
|
+
/** CTA button label. Defaults to "Learn more". */
|
|
25
|
+
buttonText?: string;
|
|
26
|
+
|
|
27
|
+
/* ── shared ── */
|
|
28
|
+
/** Display site/domain (footer for meta, header line for google). */
|
|
29
|
+
site?: string;
|
|
30
|
+
|
|
31
|
+
/* ── google props ── */
|
|
32
|
+
/** Display URL breadcrumb. HTML allowed — wrap the domain in <strong>. */
|
|
33
|
+
url?: string;
|
|
34
|
+
/** The blue clickable headline. Plain text. */
|
|
35
|
+
headline?: string;
|
|
36
|
+
/** Description line under the headline. Plain text. */
|
|
37
|
+
description?: string;
|
|
38
|
+
/** Optional sitelink labels shown in a dashed-divider row. */
|
|
39
|
+
sitelinks?: string[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function AdPreview({
|
|
43
|
+
platform = "meta",
|
|
44
|
+
brand,
|
|
45
|
+
sponsored = "Sponsored",
|
|
46
|
+
copy,
|
|
47
|
+
image,
|
|
48
|
+
site,
|
|
49
|
+
buttonText,
|
|
50
|
+
headline,
|
|
51
|
+
url,
|
|
52
|
+
description,
|
|
53
|
+
sitelinks,
|
|
54
|
+
}: AdPreviewProps) {
|
|
55
|
+
if (platform === "google") {
|
|
56
|
+
return (
|
|
57
|
+
<div className="bk-ad-preview bk-ad-preview--google">
|
|
58
|
+
<div className="bk-ad-preview__g-head">
|
|
59
|
+
<span className="bk-ad-preview__g-tag">Ad</span>
|
|
60
|
+
<span className="bk-ad-preview__g-dot" aria-hidden="true">·</span>
|
|
61
|
+
<span className="bk-ad-preview__g-site">{site}</span>
|
|
62
|
+
</div>
|
|
63
|
+
<div className="bk-ad-preview__g-url" dangerouslySetInnerHTML={{ __html: url || "" }} />
|
|
64
|
+
<h4 className="bk-ad-preview__g-headline">{headline}</h4>
|
|
65
|
+
<p className="bk-ad-preview__g-desc">{description}</p>
|
|
66
|
+
{sitelinks && sitelinks.length > 0 && (
|
|
67
|
+
<div className="bk-ad-preview__g-sitelinks">
|
|
68
|
+
{sitelinks.map((s) => (
|
|
69
|
+
<span key={s} className="bk-ad-preview__g-sitelink">{s}</span>
|
|
70
|
+
))}
|
|
71
|
+
</div>
|
|
72
|
+
)}
|
|
73
|
+
</div>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<div className="bk-ad-preview">
|
|
79
|
+
<div className="bk-ad-preview__head">
|
|
80
|
+
<div className="bk-ad-preview__avatar">{(brand || "").slice(0, 2).toUpperCase()}</div>
|
|
81
|
+
<div className="bk-ad-preview__head-text">
|
|
82
|
+
<div className="bk-ad-preview__brand">{brand}</div>
|
|
83
|
+
<div className="bk-ad-preview__sponsored">{sponsored}</div>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
<div className="bk-ad-preview__copy" dangerouslySetInnerHTML={{ __html: copy || "" }} />
|
|
87
|
+
<div className="bk-ad-preview__media">{image && <img src={image} alt="" />}</div>
|
|
88
|
+
<div className="bk-ad-preview__cta">
|
|
89
|
+
<div className="bk-ad-preview__site"><strong>{site}</strong></div>
|
|
90
|
+
<button className="bk-ad-preview__btn" type="button">{buttonText || "Learn more"}</button>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/* blog-kit React adapter — AdPreviewPair
|
|
2
|
+
Thin wrapper: all styling lives in core/css/components.css (.bk-ad-preview-pair).
|
|
3
|
+
A layout container that lays two ad-mockup cards side by side (e.g. a Meta
|
|
4
|
+
creative next to a Google text ad), collapsing to a single column on narrow
|
|
5
|
+
screens. Children carry the actual ad markup — this just owns the grid.
|
|
6
|
+
Ported from hjd's b-ads (no colours of its own, so nothing to remap). */
|
|
7
|
+
import type { ReactNode } from "react";
|
|
8
|
+
|
|
9
|
+
export interface AdPreviewPairProps {
|
|
10
|
+
/** The ad cards to lay out side by side (typically two). */
|
|
11
|
+
children?: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function AdPreviewPair({ children }: AdPreviewPairProps) {
|
|
15
|
+
return <div className="bk-ad-preview-pair">{children}</div>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/* blog-kit React adapter — AuditFindings
|
|
2
|
+
Thin wrapper: all styling lives in core/css/components.css (.bk-audit-findings).
|
|
3
|
+
A bordered, divided list of audit findings. Each row leads with a small
|
|
4
|
+
severity dot (high / med / low), then a title + description block, and a
|
|
5
|
+
pill-shaped count on the right. Severity tone is a token-driven CSS class so
|
|
6
|
+
the SAME component renders in each pack's state colours. Ported from hjd's
|
|
7
|
+
blog AuditFindings (b-saf; #fff panel + danger/warn/success dots mapped to
|
|
8
|
+
tokens). */
|
|
9
|
+
|
|
10
|
+
export type AuditFindingSeverity = "high" | "med" | "low";
|
|
11
|
+
|
|
12
|
+
export interface AuditFindingRow {
|
|
13
|
+
title: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
/** Pill-shaped count shown on the right (string or number). */
|
|
16
|
+
count?: string | number;
|
|
17
|
+
/** Severity tone of the leading dot. Defaults to "med". */
|
|
18
|
+
severity?: AuditFindingSeverity;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface AuditFindingsProps {
|
|
22
|
+
rows?: AuditFindingRow[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function AuditFindings({ rows = [] }: AuditFindingsProps) {
|
|
26
|
+
return (
|
|
27
|
+
<div className="bk-audit-findings">
|
|
28
|
+
{rows.map((r, i) => (
|
|
29
|
+
<div key={i} className="bk-audit-findings__row">
|
|
30
|
+
<span
|
|
31
|
+
className={`bk-audit-findings__sev bk-audit-findings__sev--${r.severity || "med"}`}
|
|
32
|
+
aria-hidden="true"
|
|
33
|
+
/>
|
|
34
|
+
<div className="bk-audit-findings__body">
|
|
35
|
+
<div className="bk-audit-findings__title">{r.title}</div>
|
|
36
|
+
{r.description && <div className="bk-audit-findings__desc">{r.description}</div>}
|
|
37
|
+
</div>
|
|
38
|
+
{r.count != null && <span className="bk-audit-findings__count">{r.count}</span>}
|
|
39
|
+
</div>
|
|
40
|
+
))}
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/* blog-kit React adapter — AuditScores
|
|
2
|
+
Thin wrapper: all styling lives in core/css/components.css (.bk-audit-scores).
|
|
3
|
+
A row of semicircular score gauges (0–100). Each card draws a faint track
|
|
4
|
+
arc plus a coloured progress arc whose sweep is computed from the score, a
|
|
5
|
+
big tone-coloured number, an uppercase label, and an optional sub-line.
|
|
6
|
+
Tone (good / warn / bad) is expressed purely as a token-driven CSS class —
|
|
7
|
+
the gauge arc + number inherit it via currentColor, so the SAME component
|
|
8
|
+
renders in each pack's brand colour. Ported from hjd's blog AuditScores
|
|
9
|
+
(hardcoded #10C8F0 / #FFB020 / #F04D4D / #EDEFF2 mapped to tokens). */
|
|
10
|
+
|
|
11
|
+
export interface AuditScoreItem {
|
|
12
|
+
label: string;
|
|
13
|
+
/** Optional secondary line under the label. */
|
|
14
|
+
sub?: string;
|
|
15
|
+
/** 0–100. */
|
|
16
|
+
score: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface AuditScoresProps {
|
|
20
|
+
items?: AuditScoreItem[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
type Tone = "good" | "warn" | "bad";
|
|
24
|
+
|
|
25
|
+
/** Threshold ladder ported verbatim from the hjd source. */
|
|
26
|
+
function scoreTone(score: number): Tone {
|
|
27
|
+
if (score >= 80) return "good";
|
|
28
|
+
if (score >= 50) return "warn";
|
|
29
|
+
return "bad";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** End point of the progress arc along the semicircle (r=40, cx=50, cy=50). */
|
|
33
|
+
function arcEnd(score: number): { x: string; y: string } {
|
|
34
|
+
const angle = Math.PI * (1 - score / 100);
|
|
35
|
+
return {
|
|
36
|
+
x: (50 - 40 * Math.cos(angle)).toFixed(2),
|
|
37
|
+
y: (50 - 40 * Math.sin(angle)).toFixed(2),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function AuditScores({ items = [] }: AuditScoresProps) {
|
|
42
|
+
return (
|
|
43
|
+
<div className="bk-audit-scores">
|
|
44
|
+
{items.map((it, i) => {
|
|
45
|
+
const tone = scoreTone(it.score);
|
|
46
|
+
const { x, y } = arcEnd(it.score);
|
|
47
|
+
return (
|
|
48
|
+
<div key={i} className={`bk-audit-scores__card bk-audit-scores__card--${tone}`}>
|
|
49
|
+
<svg className="bk-audit-scores__gauge" viewBox="0 0 100 60" aria-hidden="true">
|
|
50
|
+
<path
|
|
51
|
+
className="bk-audit-scores__track"
|
|
52
|
+
d="M10 50 A 40 40 0 0 1 90 50"
|
|
53
|
+
fill="none"
|
|
54
|
+
strokeWidth="8"
|
|
55
|
+
strokeLinecap="round"
|
|
56
|
+
/>
|
|
57
|
+
<path
|
|
58
|
+
className="bk-audit-scores__arc"
|
|
59
|
+
d={`M10 50 A 40 40 0 0 1 ${x} ${y}`}
|
|
60
|
+
fill="none"
|
|
61
|
+
strokeWidth="8"
|
|
62
|
+
strokeLinecap="round"
|
|
63
|
+
/>
|
|
64
|
+
</svg>
|
|
65
|
+
<div className="bk-audit-scores__num">{it.score}</div>
|
|
66
|
+
<div className="bk-audit-scores__label">{it.label}</div>
|
|
67
|
+
{it.sub && <div className="bk-audit-scores__sub">{it.sub}</div>}
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
})}
|
|
71
|
+
</div>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { authorInitials, type AuthorLink } from "../core/lib";
|
|
2
|
+
|
|
3
|
+
export interface AuthorCardProps {
|
|
4
|
+
name: string;
|
|
5
|
+
role?: string;
|
|
6
|
+
avatar?: string;
|
|
7
|
+
bio?: string;
|
|
8
|
+
links?: AuthorLink[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function AuthorCard({ name, role, avatar, bio, links }: AuthorCardProps) {
|
|
12
|
+
return (
|
|
13
|
+
<div className="bk-author">
|
|
14
|
+
<div className="bk-author__media">
|
|
15
|
+
{avatar ? (
|
|
16
|
+
<img className="bk-author__avatar" src={avatar} alt={name} />
|
|
17
|
+
) : (
|
|
18
|
+
<span className="bk-author__avatar bk-author__avatar--fallback" aria-hidden="true">{authorInitials(name)}</span>
|
|
19
|
+
)}
|
|
20
|
+
</div>
|
|
21
|
+
<div className="bk-author__body">
|
|
22
|
+
<p className="bk-author__name">{name}</p>
|
|
23
|
+
{role && <p className="bk-author__role">{role}</p>}
|
|
24
|
+
{bio && <p className="bk-author__bio">{bio}</p>}
|
|
25
|
+
{links && links.length > 0 && (
|
|
26
|
+
<div className="bk-author__links">
|
|
27
|
+
{links.map((l, i) => (
|
|
28
|
+
<a key={i} className="bk-author__link" href={l.href}>{l.label} →</a>
|
|
29
|
+
))}
|
|
30
|
+
</div>
|
|
31
|
+
)}
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface BeforeAfterSide {
|
|
2
|
+
title: string;
|
|
3
|
+
content: string;
|
|
4
|
+
/** Optional big number shown between title and content. */
|
|
5
|
+
value?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface BeforeAfterProps {
|
|
8
|
+
before: BeforeAfterSide;
|
|
9
|
+
after: BeforeAfterSide;
|
|
10
|
+
}
|
|
11
|
+
export function BeforeAfter({ before, after }: BeforeAfterProps) {
|
|
12
|
+
if (!before || !after) return null;
|
|
13
|
+
return (
|
|
14
|
+
<div className="bk-before-after">
|
|
15
|
+
<div className="bk-before-after__card bk-before-after__card--before">
|
|
16
|
+
<div className="bk-before-after__label">{before.title}</div>
|
|
17
|
+
{before.value && <div className="bk-before-after__value">{before.value}</div>}
|
|
18
|
+
<p className="bk-before-after__body">{before.content}</p>
|
|
19
|
+
</div>
|
|
20
|
+
<div className="bk-before-after__card bk-before-after__card--after">
|
|
21
|
+
<div className="bk-before-after__label">{after.title}</div>
|
|
22
|
+
{after.value && <div className="bk-before-after__value">{after.value}</div>}
|
|
23
|
+
<p className="bk-before-after__body">{after.content}</p>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect } from "react";
|
|
4
|
+
import { usePathname } from "next/navigation";
|
|
5
|
+
import { initBlogBehaviors } from "../core/behaviors/index.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Activates the kit's interactive components (TableOfContents scrollspy,
|
|
9
|
+
* FAQ JSON-LD, table scroll hints, code copy). Drop it once inside the
|
|
10
|
+
* `.blog-root` of the post route — it renders nothing. It re-runs the
|
|
11
|
+
* behaviours after every client-side navigation (keyed on the pathname)
|
|
12
|
+
* so a freshly mounted post gets wired; each behaviour is idempotent, so
|
|
13
|
+
* re-running never double-binds an already-enhanced element.
|
|
14
|
+
*/
|
|
15
|
+
export function BlogBehaviors() {
|
|
16
|
+
const pathname = usePathname();
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
initBlogBehaviors();
|
|
19
|
+
}, [pathname]);
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/* blog-kit React adapter — CTABanner
|
|
2
|
+
Thin wrapper: all styling lives in core/css/components.css (.bk-cta-banner).
|
|
3
|
+
Dark banner with a brand radial glow, heading, description, and a CTA link. */
|
|
4
|
+
import { ICONS } from "../core/icons";
|
|
5
|
+
export interface CTABannerProps {
|
|
6
|
+
heading?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
ctaText?: string;
|
|
9
|
+
ctaHref?: string;
|
|
10
|
+
}
|
|
11
|
+
export function CTABanner({
|
|
12
|
+
heading = "See it on your own site",
|
|
13
|
+
description = "Capture AI deploys in under ten minutes — paste a tag, point at your content, watch leads land.",
|
|
14
|
+
ctaText = "Book a demo",
|
|
15
|
+
ctaHref = "/book-demo",
|
|
16
|
+
}: CTABannerProps) {
|
|
17
|
+
return (
|
|
18
|
+
<div className="bk-cta-banner">
|
|
19
|
+
<span className="bk-cta-banner__glow" aria-hidden="true" />
|
|
20
|
+
<div className="bk-cta-banner__inner">
|
|
21
|
+
<div className="bk-cta-banner__copy">
|
|
22
|
+
<h3 className="bk-cta-banner__heading">{heading}</h3>
|
|
23
|
+
<p className="bk-cta-banner__desc">{description}</p>
|
|
24
|
+
</div>
|
|
25
|
+
<a className="bk-cta-banner__cta" href={ctaHref}>
|
|
26
|
+
<span className="bk-cta-banner__cta-label">{ctaText}</span>
|
|
27
|
+
<span className="bk-cta-banner__cta-icon" aria-hidden="true" dangerouslySetInnerHTML={{ __html: ICONS["arrowRight"] }} />
|
|
28
|
+
</a>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* blog-kit React adapter — CalloutBox
|
|
2
|
+
Thin wrapper: all styling lives in core/css/components.css (.bk-callout),
|
|
3
|
+
all logic in core/lib.ts, all icon markup in core/icons.ts. */
|
|
4
|
+
import type { ReactNode } from "react";
|
|
5
|
+
import { ICONS } from "../core/icons";
|
|
6
|
+
import { resolveCalloutTone, CALLOUT_DEFAULT_TITLE } from "../core/lib";
|
|
7
|
+
|
|
8
|
+
export interface CalloutBoxProps {
|
|
9
|
+
/** Canonical. info | tip | success | warn | danger (+ aliases like note/warning). */
|
|
10
|
+
tone?: string;
|
|
11
|
+
/** Alias accepted from existing HJD posts. */
|
|
12
|
+
type?: string;
|
|
13
|
+
/** Alias accepted from existing Capture AI posts. */
|
|
14
|
+
variant?: string;
|
|
15
|
+
title?: string;
|
|
16
|
+
children?: ReactNode;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function CalloutBox({ tone, type, variant, title, children }: CalloutBoxProps) {
|
|
20
|
+
const t = resolveCalloutTone(tone ?? type ?? variant);
|
|
21
|
+
const heading = title ?? CALLOUT_DEFAULT_TITLE[t];
|
|
22
|
+
return (
|
|
23
|
+
<aside className={`bk-callout bk-callout--${t}`}>
|
|
24
|
+
<p className="bk-callout__title">
|
|
25
|
+
<span className="bk-callout__icon" dangerouslySetInnerHTML={{ __html: ICONS[t] }} />
|
|
26
|
+
{heading}
|
|
27
|
+
</p>
|
|
28
|
+
<div className="bk-callout__body">{children}</div>
|
|
29
|
+
</aside>
|
|
30
|
+
);
|
|
31
|
+
}
|