@fullstackdatasolutions/articles 1.1.0 → 1.2.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.2.0] - 2026-08-12
9
+
10
+ ### Added
11
+
12
+ - **`Breadcrumb` accepts `containerClassName`.** New optional prop, default `'max-w-7xl'` (unchanged from before), applied to the breadcrumb `<ol>` in place of the previously hardcoded value. Lets a consuming site align the breadcrumb bar's content width to its own reading column instead of the package's fixed default. Found on theroleplayersguild.com, where the breadcrumb's `max-w-7xl` sat visibly wider than the article body's `max-w-3xl` column beneath it.
13
+
14
+ ### Fixed
15
+
16
+ - **`ArticleDetailHero` byline never rendered the configured author avatar.** It always showed a generic user icon even when a single `authors[]` entry had a real `avatar` set (and even though `RelatedArticlesSection`/`ArticleCard` byline avatars worked correctly from the same data). Now resolves and renders the avatar image for the single-author case, matching the existing `ArticleCard` pattern; falls back to the icon when no avatar is set or multiple authors are configured, so existing output is unchanged unless a consumer already had `authors[].avatar` configured.
17
+
8
18
  ## [1.1.0] - 2026-08-09
9
19
 
10
20
  ### Added
package/README.md CHANGED
@@ -194,6 +194,7 @@ export default async function Page({ params }: ArticlePageProps) {
194
194
  article={article}
195
195
  authors={authors}
196
196
  categoryBasePath="/articles/category"
197
+ config={siteConfig}
197
198
  />
198
199
  <ArticleViewTracker article={article} config={siteConfig} />
199
200
  {siteConfig.showToc !== false && article.toc && article.toc.length > 0 && (
package/dist/index.cjs CHANGED
@@ -265,6 +265,7 @@ function getDisplayItems(items) {
265
265
  function Breadcrumb({
266
266
  items,
267
267
  className = "",
268
+ containerClassName = "max-w-7xl",
268
269
  showSchema = true,
269
270
  separator = ">"
270
271
  }) {
@@ -276,7 +277,7 @@ function Breadcrumb({
276
277
  {
277
278
  "aria-label": "Breadcrumb",
278
279
  className: `border-b border-border bg-background/80 px-4 py-3 text-sm text-muted-foreground ${className}`,
279
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ol", { className: "mx-auto flex max-w-7xl items-center gap-2 overflow-hidden", children: displayItems.map((item, index) => {
280
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ol", { className: `mx-auto flex items-center gap-2 overflow-hidden ${containerClassName}`, children: displayItems.map((item, index) => {
280
281
  const isLast = index === displayItems.length - 1;
281
282
  const key = `${item.name}-${index}`;
282
283
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("li", { className: "flex min-w-0 items-center gap-2", children: [
@@ -1155,6 +1156,15 @@ var import_jsx_runtime13 = require("react/jsx-runtime");
1155
1156
  function toSlug(cat) {
1156
1157
  return cat.toLowerCase().replaceAll(/\s+/g, "-").replaceAll(/[^a-z0-9-]/g, "");
1157
1158
  }
1159
+ function resolveAvatarUrl(author, config) {
1160
+ if (!author.avatar) return null;
1161
+ if (author.avatar.startsWith("http://") || author.avatar.startsWith("https://")) {
1162
+ return author.avatar;
1163
+ }
1164
+ if (!(config == null ? void 0 : config.siteUrl)) return null;
1165
+ const siteUrl = config.siteUrl.replace(/\/$/, "");
1166
+ return `${siteUrl}/articles/authors/${author.slug}/${author.avatar.replace(/^\/+/, "")}`;
1167
+ }
1158
1168
  function ArticleDetailHero({
1159
1169
  article,
1160
1170
  categoryBasePath = "/articles/category",
@@ -1272,24 +1282,36 @@ function ArticleDetailHero({
1272
1282
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Clock, { className: "h-4 w-4" }),
1273
1283
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: article.readTime })
1274
1284
  ] }),
1275
- showConfiguredAuthors && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1276
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.User, { className: "h-4 w-4" }),
1277
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
1278
- "By",
1279
- " ",
1280
- authors.map((author, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react4.Fragment, { children: [
1281
- index > 0 && ", ",
1282
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1283
- import_link8.default,
1284
- {
1285
- href: `/articles/authors/${author.slug}`,
1286
- className: "font-medium text-white underline-offset-4 hover:underline",
1287
- children: author.name
1288
- }
1289
- )
1290
- ] }, author.slug))
1291
- ] })
1292
- ] }),
1285
+ showConfiguredAuthors && (() => {
1286
+ const singleAvatarUrl = authors.length === 1 ? resolveAvatarUrl(authors[0], config) : null;
1287
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1288
+ singleAvatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1289
+ import_image5.default,
1290
+ {
1291
+ src: singleAvatarUrl,
1292
+ alt: "",
1293
+ width: 20,
1294
+ height: 20,
1295
+ className: "h-5 w-5 rounded-full object-cover"
1296
+ }
1297
+ ) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.User, { className: "h-4 w-4" }),
1298
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
1299
+ "By",
1300
+ " ",
1301
+ authors.map((author, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react4.Fragment, { children: [
1302
+ index > 0 && ", ",
1303
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1304
+ import_link8.default,
1305
+ {
1306
+ href: `/articles/authors/${author.slug}`,
1307
+ className: "font-medium text-white underline-offset-4 hover:underline",
1308
+ children: author.name
1309
+ }
1310
+ )
1311
+ ] }, author.slug))
1312
+ ] })
1313
+ ] });
1314
+ })(),
1293
1315
  showLegacyAuthor && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1294
1316
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.User, { className: "h-4 w-4" }),
1295
1317
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [