@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 +10 -0
- package/README.md +1 -0
- package/dist/index.cjs +41 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +41 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/ArticleDetailHero.tsx +44 -19
- package/src/Breadcrumb.tsx +4 -1
- package/src/__tests__/ArticleDetailHero.test.tsx +57 -0
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:
|
|
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 &&
|
|
1276
|
-
|
|
1277
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
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: [
|