@fullstackdatasolutions/articles 1.0.0 → 1.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/CHANGELOG.md CHANGED
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.1.0] - 2026-08-09
9
+
10
+ ### Added
11
+
12
+ - **Configurable heading font family.** New `ArticlesTheme.headerFontFamily`, optional and falling back to inherit/nothing when unset - existing consumers who don't set it see byte-identical output. Threaded through `ArticleDetailHero` (new optional `config` prop), `RelatedArticlesSection`, and `ArticleCard` (both already accepted `config`) via inline `style={{ fontFamily: config?.theme?.headerFontFamily }}`, and into `ArticlesPage`'s `buildThemeVars` as `--articles-header-font-family`, consistent with the package's existing CSS-var theming pattern. Lets a site use a distinct display face for headings (e.g. a serif) separate from its body `fontFamily`, without hardcoding either into the package. Found auditing theroleplayersguild.com's article pages, which use a serif heading treatment the package couldn't previously express.
13
+
14
+ ### Fixed
15
+
16
+ - **`ArticleCard` hardcoded an indigo hover color.** The title link's `hover:text-indigo-600` was a stray leftover unrelated to any theme token and would visibly clash with any site not using an indigo-ish primary color. Replaced with `hover:text-primary`, matching the token already used elsewhere in the same component.
17
+
8
18
  ## [1.0.0] - 2026-08-05
9
19
 
10
20
  ### Breaking
package/README.md CHANGED
@@ -580,17 +580,18 @@ All theme values are applied as CSS custom properties on a wrapper `<div>`. Comp
580
580
 
581
581
  ```ts
582
582
  theme: {
583
- fontFamily: "'Inter', sans-serif",
584
- headerColor: '#111827',
585
- textColor: '#6b7280',
586
- backgroundColor: '#ffffff',
587
- linkColor: '#4f46e5',
588
- linkHoverColor: '#4338ca',
589
- borderRadius: '0.5rem',
583
+ fontFamily: "'Inter', sans-serif",
584
+ headerFontFamily: "'Cinzel', serif",
585
+ headerColor: '#111827',
586
+ textColor: '#6b7280',
587
+ backgroundColor: '#ffffff',
588
+ linkColor: '#4f46e5',
589
+ linkHoverColor: '#4338ca',
590
+ borderRadius: '0.5rem',
590
591
  }
591
592
  ```
592
593
 
593
- All fields are optional. Omitted fields fall back to your Tailwind theme tokens.
594
+ All fields are optional. Omitted fields fall back to your Tailwind theme tokens. `headerFontFamily` styles article titles and card/section headings (`ArticleDetailHero`, `RelatedArticlesSection`, `ArticleCard`) separately from body text; omit it to let headings inherit `fontFamily` like everything else.
594
595
 
595
596
  ---
596
597
 
package/dist/index.cjs CHANGED
@@ -650,6 +650,7 @@ function emitArticleEvent(handler, event) {
650
650
  // src/ArticleCard.tsx
651
651
  var import_jsx_runtime8 = require("react/jsx-runtime");
652
652
  function ArticleCard({ article, config }) {
653
+ var _a;
653
654
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "rounded-lg border border-border bg-card text-card-foreground shadow-sm hover:shadow-lg transition-shadow duration-300", children: [
654
655
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "p-0", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
655
656
  import_image4.default,
@@ -663,14 +664,14 @@ function ArticleCard({ article, config }) {
663
664
  ) }),
664
665
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "p-6", children: [
665
666
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex gap-2 mb-3", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "bg-primary/10 text-primary text-xs font-medium px-2 py-1 rounded", children: article.category }) }),
666
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { className: "text-lg font-semibold leading-none tracking-tight mb-2", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
667
- import_link6.default,
667
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
668
+ "h3",
668
669
  {
669
- href: `/articles/${article.slug}`,
670
- className: "hover:text-indigo-600 transition-colors",
671
- children: article.title
670
+ className: "text-lg font-semibold leading-none tracking-tight mb-2",
671
+ style: { fontFamily: (_a = config == null ? void 0 : config.theme) == null ? void 0 : _a.headerFontFamily },
672
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_link6.default, { href: `/articles/${article.slug}`, className: "hover:text-primary transition-colors", children: article.title })
672
673
  }
673
- ) }),
674
+ ),
674
675
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-muted-foreground mb-4 line-clamp-3", children: article.excerpt }),
675
676
  article.authorSlug && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
676
677
  import_link6.default,
@@ -993,6 +994,7 @@ function buildThemeVars(theme) {
993
994
  if (!theme) return {};
994
995
  const vars = {};
995
996
  if (theme.fontFamily) vars["--articles-font-family"] = theme.fontFamily;
997
+ if (theme.headerFontFamily) vars["--articles-header-font-family"] = theme.headerFontFamily;
996
998
  if (theme.headerColor) vars["--articles-header-color"] = theme.headerColor;
997
999
  if (theme.textColor) vars["--articles-text-color"] = theme.textColor;
998
1000
  if (theme.backgroundColor) vars["--articles-bg-color"] = theme.backgroundColor;
@@ -1158,8 +1160,10 @@ function ArticleDetailHero({
1158
1160
  categoryBasePath = "/articles/category",
1159
1161
  showDate = false,
1160
1162
  showAuthor = true,
1161
- authors = []
1163
+ authors = [],
1164
+ config
1162
1165
  }) {
1166
+ var _a;
1163
1167
  const showConfiguredAuthors = showAuthor && authors.length > 0;
1164
1168
  const showLegacyAuthor = showAuthor && authors.length === 0 && article.author.trim().length > 0;
1165
1169
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
@@ -1240,7 +1244,14 @@ function ArticleDetailHero({
1240
1244
  )
1241
1245
  }
1242
1246
  ),
1243
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h1", { className: "text-4xl md:text-5xl font-bold mb-4", children: article.title }),
1247
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1248
+ "h1",
1249
+ {
1250
+ className: "text-4xl md:text-5xl font-bold mb-4",
1251
+ style: { fontFamily: (_a = config == null ? void 0 : config.theme) == null ? void 0 : _a.headerFontFamily },
1252
+ children: article.title
1253
+ }
1254
+ ),
1244
1255
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1245
1256
  "div",
1246
1257
  {
@@ -2006,9 +2017,17 @@ function RelatedArticlesSection({
2006
2017
  fromSlug,
2007
2018
  source = "category"
2008
2019
  }) {
2020
+ var _a;
2009
2021
  if (articles.length === 0) return null;
2010
2022
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("section", { className: "mt-12 pt-8 border-t border-border", "aria-label": "Related articles", children: [
2011
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h2", { className: "text-xl font-semibold text-foreground mb-6", children: heading != null ? heading : `More in ${category}` }),
2023
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2024
+ "h2",
2025
+ {
2026
+ className: "text-xl font-semibold text-foreground mb-6",
2027
+ style: { fontFamily: (_a = config == null ? void 0 : config.theme) == null ? void 0 : _a.headerFontFamily },
2028
+ children: heading != null ? heading : `More in ${category}`
2029
+ }
2030
+ ),
2012
2031
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "grid gap-6 sm:grid-cols-2 lg:grid-cols-3", children: articles.map((article) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2013
2032
  "div",
2014
2033
  {