From 1f8e15b5acb4f14a0c1e60f8972b7762dae61a21 Mon Sep 17 00:00:00 2001 From: Kevin Van Cott Date: Mon, 11 May 2026 12:47:25 -0500 Subject: [PATCH 1/3] feat: blog post filters by author and new blog post entry page per library --- src/components/BlogAuthorFilter.tsx | 57 +++++ src/components/BlogCard.tsx | 86 ++++++++ src/components/DocsLayout.tsx | 4 + src/images/author-fallback.svg | 5 + src/libraries/maintainers.ts | 11 +- src/routeTree.gen.ts | 22 ++ src/routes/$libraryId/$version.docs.blog.tsx | 111 ++++++++++ src/routes/blog.index.tsx | 209 +++++++++---------- src/utils/authors.ts | 7 + src/utils/blog.ts | 36 ++++ 10 files changed, 429 insertions(+), 119 deletions(-) create mode 100644 src/components/BlogAuthorFilter.tsx create mode 100644 src/components/BlogCard.tsx create mode 100644 src/images/author-fallback.svg create mode 100644 src/routes/$libraryId/$version.docs.blog.tsx create mode 100644 src/utils/authors.ts diff --git a/src/components/BlogAuthorFilter.tsx b/src/components/BlogAuthorFilter.tsx new file mode 100644 index 000000000..66baf758a --- /dev/null +++ b/src/components/BlogAuthorFilter.tsx @@ -0,0 +1,57 @@ +import { Select, type SelectOption } from '~/components/Select' +import { findMaintainerByAuthorName } from '~/utils/authors' +import authorFallbackAvatar from '~/images/author-fallback.svg' + +const ALL_AUTHORS_VALUE = 'all' + +function getAuthorAvatar(name: string): string { + return findMaintainerByAuthorName(name)?.avatar ?? authorFallbackAvatar +} + +type BlogAuthorFilterProps = { + authors: string[] + selected: string | undefined + onSelect: (author: string | undefined) => void + className?: string +} + +export function BlogAuthorFilter({ + authors, + selected, + onSelect, + className, +}: BlogAuthorFilterProps) { + const available: SelectOption[] = [ + { label: 'All authors', value: ALL_AUTHORS_VALUE }, + ...authors.map((name) => ({ + label: name, + value: name, + logo: getAuthorAvatar(name), + })), + ] + + // If the URL has an author that isn't in the post list, surface it anyway + // so the trigger renders and the user can still reset to "All authors". + if ( + selected && + selected !== ALL_AUTHORS_VALUE && + !authors.includes(selected) + ) { + available.push({ + label: selected, + value: selected, + logo: getAuthorAvatar(selected), + }) + } + + return ( + - onSelect(option.value === ALL_AUTHORS_VALUE ? undefined : option.value) - } - /> +
+ + + + + + onSelect(undefined)} + className={twMerge( + 'pr-8 relative', + !activeAuthor + ? 'bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-200 font-medium' + : 'font-normal', + )} + > + All authors + {!activeAuthor ? ( + + {authors.length > 0 ? : null} + {authors.map((name) => { + const isSelected = activeAuthor === name + return ( + onSelect(name)} + className={twMerge( + 'pr-8 pl-2 relative', + isSelected + ? 'bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-200 font-medium' + : 'font-normal', + )} + > + + {name} + {isSelected ? ( + + ) + })} + + +
) } diff --git a/src/libraries/maintainers.ts b/src/libraries/maintainers.ts index 366367cb3..e41cb02e5 100644 --- a/src/libraries/maintainers.ts +++ b/src/libraries/maintainers.ts @@ -38,9 +38,11 @@ export const allMaintainers: Maintainer[] = [ 'ranger', 'store', 'pacer', + 'cli', 'mcp', 'react-charts', ], + maintainerOf: ['intent'], frameworkExpertise: ['react', 'solid'], specialties: ['Architecture', 'Core API', 'Documentation'], social: { @@ -162,7 +164,7 @@ export const allMaintainers: Maintainer[] = [ isCoreMaintainer: true, avatar: 'https://github.com/KyleAMathews.png', github: 'KyleAMathews', - creatorOf: ['db'], + creatorOf: ['db', 'intent'], frameworkExpertise: ['react'], specialties: ['Sync Engines'], }, @@ -306,6 +308,7 @@ export const allMaintainers: Maintainer[] = [ name: 'Sarah Gerrard', avatar: 'https://github.com/ladybluenotes.png', github: 'ladybluenotes', + creatorOf: ['intent'], contributorOf: [ 'ai', 'config', From 58c7a64b16f4db7c607c3422c1312255ab981549 Mon Sep 17 00:00:00 2001 From: Kevin Van Cott Date: Mon, 11 May 2026 13:34:29 -0500 Subject: [PATCH 3/3] fix select lint error --- src/components/shop/ui/Select.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/shop/ui/Select.tsx b/src/components/shop/ui/Select.tsx index 50b63d00b..dc98ffcb1 100644 --- a/src/components/shop/ui/Select.tsx +++ b/src/components/shop/ui/Select.tsx @@ -94,12 +94,13 @@ export function ShopSelect({ } return ( -
+