From 712922a3c22b0520ad574b0d893a9ee58f45bddc Mon Sep 17 00:00:00 2001 From: Kevin Van Cott Date: Tue, 3 Jun 2025 20:33:31 -0500 Subject: [PATCH 01/20] feat: contributors pages for repos --- src/components/ContributorsWall.tsx | 19 ++ src/components/DocsLayout.tsx | 4 + src/components/MaintainerCard.tsx | 87 ++++++ src/libraries/index.tsx | 3 +- src/libraries/maintainers.ts | 266 ++++++++++++++++++ src/routeTree.gen.ts | 37 +++ .../$libraryId/$version.docs.contributors.tsx | 55 ++++ src/routes/_libraries/route.tsx | 18 +- 8 files changed, 487 insertions(+), 2 deletions(-) create mode 100644 src/components/ContributorsWall.tsx create mode 100644 src/components/MaintainerCard.tsx create mode 100644 src/libraries/maintainers.ts create mode 100644 src/routes/$libraryId/$version.docs.contributors.tsx diff --git a/src/components/ContributorsWall.tsx b/src/components/ContributorsWall.tsx new file mode 100644 index 000000000..58dbb059a --- /dev/null +++ b/src/components/ContributorsWall.tsx @@ -0,0 +1,19 @@ +import { type Library } from '~/libraries' + +export function ContributorsWall({ library }: { library: Library }) { + return ( + + + + + + ) +} diff --git a/src/components/DocsLayout.tsx b/src/components/DocsLayout.tsx index 5a352eaab..f80ffa3da 100644 --- a/src/components/DocsLayout.tsx +++ b/src/components/DocsLayout.tsx @@ -197,6 +197,10 @@ const useMenuConfig = ({ }, ] : []), + { + label: 'Contributors', + to: '/$libraryId/$version/docs/contributors', + }, { label: ( diff --git a/src/components/MaintainerCard.tsx b/src/components/MaintainerCard.tsx new file mode 100644 index 000000000..7e3eaebaa --- /dev/null +++ b/src/components/MaintainerCard.tsx @@ -0,0 +1,87 @@ +import { Library } from '~/libraries' +import { getRoleInLibrary, Maintainer } from '~/libraries/maintainers' + +function RoleBadge({ role, libraryId }: { role: string; libraryId: string }) { + const isCreator = role.toLowerCase().includes('creator') + const isMaintainer = role.toLowerCase().includes('maintainer') + + if (isCreator) { + return ( + + {role} + + ) + } + + if (isMaintainer) { + return ( + + {role} + + ) + } + + return {role} +} + +interface MaintainerCardProps { + maintainer: Maintainer + libraryId: Library['id'] +} + +export function MaintainerCard({ maintainer, libraryId }: MaintainerCardProps) { + return ( + + + + + + + + {maintainer.name} + + + + + + + + + + @{maintainer.github} + + + + {maintainer.specialties?.map((specialty: string) => ( + + {specialty} + + ))} + + + + ) +} diff --git a/src/libraries/index.tsx b/src/libraries/index.tsx index 0c146a92b..028fe153e 100644 --- a/src/libraries/index.tsx +++ b/src/libraries/index.tsx @@ -57,6 +57,7 @@ export type Library = { | 'db' | 'config' | 'react-charts' + | 'create-ts-router-app' name: string cardStyles: string to: string @@ -125,7 +126,6 @@ export const librariesByGroup = { } export const librariesGroupNamesMap = { - app: 'Application Building', state: 'Data and State Management', headlessUI: 'Headless UI', other: 'Other', @@ -165,3 +165,4 @@ export function getBranch(library: Library, argVersion?: string) { return resolvedVersion } + diff --git a/src/libraries/maintainers.ts b/src/libraries/maintainers.ts new file mode 100644 index 000000000..68db85799 --- /dev/null +++ b/src/libraries/maintainers.ts @@ -0,0 +1,266 @@ +import { Framework, getLibrary, Library } from '.' + +export interface Maintainer { + name: string + avatar: string + github: string + isCoreMaintainer: boolean + creatorOf?: Library['id'][] + maintainerOf?: Library['id'][] // inherits from creatorOf + contributorOf?: Library['id'][] // inherits from maintainerOf + consultantOf?: Library['id'][] // inherits from maintainerOf + frameworkExpertise?: Framework[] + specialties?: string[] + social?: { + twitter?: string + bluesky?: string + website?: string + } +} + +// order matters +export const allMaintainers: Maintainer[] = [ + { + name: 'Tanner Linsley', + isCoreMaintainer: true, + avatar: 'https://github.com/tannerlinsley.png', + github: 'tannerlinsley', + creatorOf: [ + 'start', + 'router', + 'query', + 'table', + 'form', + 'virtual', + 'ranger', + 'store', + 'react-charts', + ], + frameworkExpertise: ['react', 'solid'], + specialties: ['Architecture', 'Core API', 'Documentation'], + }, + { + name: 'Dominik Dorfmeister', + isCoreMaintainer: true, + avatar: 'https://github.com/tkdodo.png', + github: 'tkdodo', + maintainerOf: ['query'], + contributorOf: ['router'], + frameworkExpertise: ['react'], + specialties: ['Core API', 'TypeScript', 'Documentation'], + }, + { + name: 'Corbin Crutchley', + isCoreMaintainer: true, + avatar: 'https://github.com/crutchcorn.png', + github: 'crutchcorn', + creatorOf: ['form'], + maintainerOf: ['store'], + frameworkExpertise: ['react', 'solid', 'vue', 'angular'], + specialties: ['Forms', 'Validation', 'State Management'], + }, + { + name: 'Manual Schiller', + isCoreMaintainer: true, + avatar: 'https://github.com/schiller-manuel.png', + github: 'schiller-manuel', + maintainerOf: ['start', 'router'], + frameworkExpertise: ['react'], + specialties: [], + }, + { + name: 'Kevin Van Cott', + isCoreMaintainer: true, + avatar: 'https://github.com/kevinvandy.png', + github: 'kevinvandy', + creatorOf: ['pacer'], + maintainerOf: ['table'], + contributorOf: ['virtual'], + consultantOf: ['query'], + frameworkExpertise: ['react', 'solid', 'svelte'], + specialties: ['Tables', 'Data Grids', 'Dashboards'], + }, + { + name: 'Sean Cassiere', + isCoreMaintainer: true, + avatar: 'https://github.com/seancassiere.png', + github: 'seancassiere', + maintainerOf: ['start', 'router'], + frameworkExpertise: ['react'], + specialties: [], + }, + { + name: 'Chris Horobin', + isCoreMaintainer: true, + avatar: 'https://github.com/chorobin.png', + github: 'chorobin', + maintainerOf: ['router'], + frameworkExpertise: ['react'], + specialties: ['TypeScript'], + }, + { + name: 'Damian Pieczynski', + isCoreMaintainer: true, + avatar: 'https://github.com/piecyk.png', + github: 'piecyk', + maintainerOf: ['virtual'], + frameworkExpertise: ['react'], + specialties: ['Virtualization', 'Performance'], + }, + { + name: 'Jack Herrington', + isCoreMaintainer: true, + avatar: 'https://github.com/jherr.png', + github: 'jherr', + creatorOf: ['create-ts-router-app'], + frameworkExpertise: ['react'], + specialties: ['Templates'], + }, + { + name: 'Kyle Mathews', + isCoreMaintainer: true, + avatar: 'https://github.com/KyleAMathews.png', + github: 'KyleAMathews', + creatorOf: ['create-ts-router-app'], + frameworkExpertise: ['react'], + specialties: ['Sync Engines'], + }, + { + name: 'Lachlan Collins', + isCoreMaintainer: true, + avatar: 'https://github.com/lachlancollins.png', + github: 'lachlancollins', + maintainerOf: ['config'], + frameworkExpertise: ['react', 'svelte'], + specialties: ['Architecture'], + }, +] + +export const coreMaintainers = allMaintainers.filter( + (maintainer) => maintainer.isCoreMaintainer +) + +export function getLibraryCreators(libraryId: string): Maintainer[] { + return allMaintainers.filter((maintainer) => + maintainer.creatorOf?.includes(libraryId as Library['id']) + ) +} + +export function getLibraryMaintainers( + libraryId: string, + includeCreators = true +): Maintainer[] { + const creators = getLibraryCreators(libraryId) + const maintainers = allMaintainers.filter((maintainer) => + maintainer.maintainerOf?.includes(libraryId as Library['id']) + ) + + // Use Set to dedupe while preserving order + return includeCreators + ? [...new Set([...creators, ...maintainers])] + : maintainers +} + +export function getLibraryContributors( + libraryId: string, + includeMaintainers = true +): Maintainer[] { + const maintainers = getLibraryMaintainers(libraryId) + const contributors = allMaintainers.filter((maintainer) => + maintainer.contributorOf?.includes(libraryId as Library['id']) + ) + + return includeMaintainers + ? [...new Set([...maintainers, ...contributors])] + : contributors +} + +export function getLibraryConsultants( + libraryId: string, + includeMaintainers = true +): Maintainer[] { + const maintainers = getLibraryMaintainers(libraryId) + const consultants = allMaintainers.filter((maintainer) => + maintainer.consultantOf?.includes(libraryId as Library['id']) + ) + + return includeMaintainers + ? [...new Set([...maintainers, ...consultants])] + : consultants +} + +export function getPersonsCreatorOf(person: Maintainer): Library[] { + return person.creatorOf?.map((libraryId) => getLibrary(libraryId)) || [] +} + +export function getPersonsMaintainerOf( + person: Maintainer, + includeCreatorOf = true +): Library[] { + const creatorOf = getPersonsCreatorOf(person) + const maintainerOf = + person.maintainerOf?.map((libraryId) => getLibrary(libraryId)) || [] + + return includeCreatorOf + ? [...new Set([...creatorOf, ...maintainerOf])] + : maintainerOf +} + +export function getPersonsContributorOf( + person: Maintainer, + includeMaintainers = true +): Library[] { + const maintainers = getPersonsMaintainerOf(person) + const contributors = + person.contributorOf?.map((libraryId) => getLibrary(libraryId)) || [] + + return includeMaintainers + ? [...new Set([...maintainers, ...contributors])] + : contributors +} + +export function getPersonsConsultantOf( + person: Maintainer, + includeMaintainers = true +): Library[] { + const maintainers = getPersonsMaintainerOf(person) + const consultants = + person.consultantOf?.map((libraryId) => getLibrary(libraryId)) || [] + + return includeMaintainers + ? [...new Set([...maintainers, ...consultants])] + : consultants +} + +export function getIsCreatorOfLibrary(person: Maintainer, libraryId: string) { + return person.creatorOf?.includes(libraryId as Library['id']) +} + +export function getIsMaintainerOfLibrary( + person: Maintainer, + libraryId: string +) { + return person.maintainerOf?.includes(libraryId as Library['id']) +} + +export function getIsContributorOfLibrary( + person: Maintainer, + libraryId: string +) { + return person.contributorOf?.includes(libraryId as Library['id']) +} + +export function getIsConsultantOfLibrary( + person: Maintainer, + libraryId: string +) { + return person.consultantOf?.includes(libraryId as Library['id']) +} + +export function getRoleInLibrary(person: Maintainer, libraryId: string) { + if (getIsCreatorOfLibrary(person, libraryId)) return 'Creator' + if (getIsMaintainerOfLibrary(person, libraryId)) return 'Maintainer' + if (getIsContributorOfLibrary(person, libraryId)) return 'Contributor' + if (getIsConsultantOfLibrary(person, libraryId)) return 'Consultant' + return 'Contributor' +} diff --git a/src/routeTree.gen.ts b/src/routeTree.gen.ts index 15f7e0cc8..5603f1dd3 100644 --- a/src/routeTree.gen.ts +++ b/src/routeTree.gen.ts @@ -46,6 +46,7 @@ import { Route as LibrariesFormVersionIndexRouteImport } from './routes/_librari import { Route as LibrariesDbVersionIndexRouteImport } from './routes/_libraries/db.$version.index' import { Route as LibrariesConfigVersionIndexRouteImport } from './routes/_libraries/config.$version.index' import { Route as LibraryIdVersionDocsIndexRouteImport } from './routes/$libraryId/$version.docs.index' +import { Route as LibraryIdVersionDocsContributorsRouteImport } from './routes/$libraryId/$version.docs.contributors' import { Route as LibraryIdVersionDocsSplatRouteImport } from './routes/$libraryId/$version.docs.$' import { Route as LibraryIdVersionDocsFrameworkIndexRouteImport } from './routes/$libraryId/$version.docs.framework.index' import { Route as LibraryIdVersionDocsFrameworkFrameworkIndexRouteImport } from './routes/$libraryId/$version.docs.framework.$framework.index' @@ -263,6 +264,13 @@ const LibraryIdVersionDocsIndexRoute = getParentRoute: () => LibraryIdVersionDocsRoute, } as any) +const LibraryIdVersionDocsContributorsRoute = + LibraryIdVersionDocsContributorsRouteImport.update({ + id: '/contributors', + path: '/contributors', + getParentRoute: () => LibraryIdVersionDocsRoute, + } as any) + const LibraryIdVersionDocsSplatRoute = LibraryIdVersionDocsSplatRouteImport.update({ id: '/$', @@ -456,6 +464,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof LibraryIdVersionDocsSplatRouteImport parentRoute: typeof LibraryIdVersionDocsRouteImport } + '/$libraryId/$version/docs/contributors': { + id: '/$libraryId/$version/docs/contributors' + path: '/contributors' + fullPath: '/$libraryId/$version/docs/contributors' + preLoaderRoute: typeof LibraryIdVersionDocsContributorsRouteImport + parentRoute: typeof LibraryIdVersionDocsRouteImport + } '/$libraryId/$version/docs/': { id: '/$libraryId/$version/docs/' path: '/' @@ -771,6 +786,15 @@ declare module './routes/$libraryId/$version.docs.$' { FileRoutesByPath['/$libraryId/$version/docs/$']['fullPath'] > } +declare module './routes/$libraryId/$version.docs.contributors' { + const createFileRoute: CreateFileRoute< + '/$libraryId/$version/docs/contributors', + FileRoutesByPath['/$libraryId/$version/docs/contributors']['parentRoute'], + FileRoutesByPath['/$libraryId/$version/docs/contributors']['id'], + FileRoutesByPath['/$libraryId/$version/docs/contributors']['path'], + FileRoutesByPath['/$libraryId/$version/docs/contributors']['fullPath'] + > +} declare module './routes/$libraryId/$version.docs.index' { const createFileRoute: CreateFileRoute< '/$libraryId/$version/docs/', @@ -920,6 +944,7 @@ declare module './routes/$libraryId/$version.docs.framework.$framework.examples. interface LibraryIdVersionDocsRouteChildren { LibraryIdVersionDocsSplatRoute: typeof LibraryIdVersionDocsSplatRoute + LibraryIdVersionDocsContributorsRoute: typeof LibraryIdVersionDocsContributorsRoute LibraryIdVersionDocsIndexRoute: typeof LibraryIdVersionDocsIndexRoute LibraryIdVersionDocsFrameworkIndexRoute: typeof LibraryIdVersionDocsFrameworkIndexRoute LibraryIdVersionDocsFrameworkFrameworkSplatRoute: typeof LibraryIdVersionDocsFrameworkFrameworkSplatRoute @@ -929,6 +954,7 @@ interface LibraryIdVersionDocsRouteChildren { const LibraryIdVersionDocsRouteChildren: LibraryIdVersionDocsRouteChildren = { LibraryIdVersionDocsSplatRoute: LibraryIdVersionDocsSplatRoute, + LibraryIdVersionDocsContributorsRoute: LibraryIdVersionDocsContributorsRoute, LibraryIdVersionDocsIndexRoute: LibraryIdVersionDocsIndexRoute, LibraryIdVersionDocsFrameworkIndexRoute: LibraryIdVersionDocsFrameworkIndexRoute, @@ -1053,6 +1079,7 @@ export interface FileRoutesByFullPath { '/blog/': typeof LibrariesBlogIndexRoute '/stats/npm': typeof StatsNpmIndexRoute '/$libraryId/$version/docs/$': typeof LibraryIdVersionDocsSplatRoute + '/$libraryId/$version/docs/contributors': typeof LibraryIdVersionDocsContributorsRoute '/$libraryId/$version/docs/': typeof LibraryIdVersionDocsIndexRoute '/config/$version': typeof LibrariesConfigVersionIndexRoute '/db/$version': typeof LibrariesDbVersionIndexRoute @@ -1090,6 +1117,7 @@ export interface FileRoutesByTo { '/blog': typeof LibrariesBlogIndexRoute '/stats/npm': typeof StatsNpmIndexRoute '/$libraryId/$version/docs/$': typeof LibraryIdVersionDocsSplatRoute + '/$libraryId/$version/docs/contributors': typeof LibraryIdVersionDocsContributorsRoute '/$libraryId/$version/docs': typeof LibraryIdVersionDocsIndexRoute '/config/$version': typeof LibrariesConfigVersionIndexRoute '/db/$version': typeof LibrariesDbVersionIndexRoute @@ -1132,6 +1160,7 @@ export interface FileRoutesById { '/_libraries/blog/': typeof LibrariesBlogIndexRoute '/stats/npm/': typeof StatsNpmIndexRoute '/$libraryId/$version/docs/$': typeof LibraryIdVersionDocsSplatRoute + '/$libraryId/$version/docs/contributors': typeof LibraryIdVersionDocsContributorsRoute '/$libraryId/$version/docs/': typeof LibraryIdVersionDocsIndexRoute '/_libraries/config/$version/': typeof LibrariesConfigVersionIndexRoute '/_libraries/db/$version/': typeof LibrariesDbVersionIndexRoute @@ -1175,6 +1204,7 @@ export interface FileRouteTypes { | '/blog/' | '/stats/npm' | '/$libraryId/$version/docs/$' + | '/$libraryId/$version/docs/contributors' | '/$libraryId/$version/docs/' | '/config/$version' | '/db/$version' @@ -1211,6 +1241,7 @@ export interface FileRouteTypes { | '/blog' | '/stats/npm' | '/$libraryId/$version/docs/$' + | '/$libraryId/$version/docs/contributors' | '/$libraryId/$version/docs' | '/config/$version' | '/db/$version' @@ -1251,6 +1282,7 @@ export interface FileRouteTypes { | '/_libraries/blog/' | '/stats/npm/' | '/$libraryId/$version/docs/$' + | '/$libraryId/$version/docs/contributors' | '/$libraryId/$version/docs/' | '/_libraries/config/$version/' | '/_libraries/db/$version/' @@ -1410,6 +1442,7 @@ export const routeTree = rootRoute "parent": "/$libraryId/$version", "children": [ "/$libraryId/$version/docs/$", + "/$libraryId/$version/docs/contributors", "/$libraryId/$version/docs/", "/$libraryId/$version/docs/framework/", "/$libraryId/$version/docs/framework/$framework/$", @@ -1432,6 +1465,10 @@ export const routeTree = rootRoute "filePath": "$libraryId/$version.docs.$.tsx", "parent": "/$libraryId/$version/docs" }, + "/$libraryId/$version/docs/contributors": { + "filePath": "$libraryId/$version.docs.contributors.tsx", + "parent": "/$libraryId/$version/docs" + }, "/$libraryId/$version/docs/": { "filePath": "$libraryId/$version.docs.index.tsx", "parent": "/$libraryId/$version/docs" diff --git a/src/routes/$libraryId/$version.docs.contributors.tsx b/src/routes/$libraryId/$version.docs.contributors.tsx new file mode 100644 index 000000000..effb5b6c2 --- /dev/null +++ b/src/routes/$libraryId/$version.docs.contributors.tsx @@ -0,0 +1,55 @@ +import { twMerge } from 'tailwind-merge' +import { DocContainer } from '~/components/DocContainer' +import { DocTitle } from '~/components/DocTitle' +import { getLibrary } from '~/libraries' +import { ContributorsWall } from '~/components/ContributorsWall' +import {} from '@tanstack/react-router' +import { getLibraryContributors } from '~/libraries/maintainers' +import { MaintainerCard } from '~/components/MaintainerCard' + +export const Route = createFileRoute({ + component: RouteComponent, +}) + +function RouteComponent() { + const { libraryId } = Route.useParams() + const library = getLibrary(libraryId) + + // Get the maintainers for this library + const libraryContributors = getLibraryContributors(libraryId) + + return ( + + + + {library.name} Maintainers and Contributors + + + + {libraryContributors.map((maintainer) => ( + + ))} + + + + + + + All Contributors + + + + + + ) +} diff --git a/src/routes/_libraries/route.tsx b/src/routes/_libraries/route.tsx index 941919fab..528e6849d 100644 --- a/src/routes/_libraries/route.tsx +++ b/src/routes/_libraries/route.tsx @@ -5,7 +5,13 @@ import { MdLibraryBooks, MdLineAxis, MdSupport } from 'react-icons/md' import { twMerge } from 'tailwind-merge' import { sortBy } from '~/utils/utils' import logoColor100w from '~/images/logo-color-100w.png' -import { FaDiscord, FaGithub, FaInstagram, FaTshirt } from 'react-icons/fa' +import { + FaDiscord, + FaGithub, + FaInstagram, + FaTshirt, + FaUsers, +} from 'react-icons/fa' import { getSponsorsForSponsorPack } from '~/server/sponsors' import { libraries } from '~/libraries' import { Scarf } from '~/components/Scarf' @@ -135,6 +141,16 @@ function LibrariesLayout() { ) })} + + + Contributors + )} From 88cbbeec0ce0fc706ba8791e4161808cb9ddf76c Mon Sep 17 00:00:00 2001 From: Kevin Van Cott Date: Tue, 3 Jun 2025 20:47:41 -0500 Subject: [PATCH 02/20] prettier --- src/libraries/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/index.tsx b/src/libraries/index.tsx index 028fe153e..a9d3fd1f7 100644 --- a/src/libraries/index.tsx +++ b/src/libraries/index.tsx @@ -165,4 +165,3 @@ export function getBranch(library: Library, argVersion?: string) { return resolvedVersion } - From f385cae411c620943f87dc7cc02175b10d632b2c Mon Sep 17 00:00:00 2001 From: Kevin Van Cott Date: Wed, 4 Jun 2025 10:56:43 -0500 Subject: [PATCH 03/20] Update src/components/MaintainerCard.tsx Co-authored-by: Leonardo Montini --- src/components/MaintainerCard.tsx | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/components/MaintainerCard.tsx b/src/components/MaintainerCard.tsx index 7e3eaebaa..6065f1fe7 100644 --- a/src/components/MaintainerCard.tsx +++ b/src/components/MaintainerCard.tsx @@ -58,16 +58,14 @@ export function MaintainerCard({ maintainer, libraryId }: MaintainerCardProps) { libraryId={libraryId} />
+ +
+ + + + + + @{maintainer.github} +
- - - - - +
+ + + @{maintainer.github}
+
{library.name} Maintainers and Contributors - + {libraryContributors.map((maintainer) => ( Date: Wed, 4 Jun 2025 14:09:17 -0500 Subject: [PATCH 11/20] update card design --- src/components/MaintainerCard.tsx | 113 ++++++++++++++++++++++-------- 1 file changed, 84 insertions(+), 29 deletions(-) diff --git a/src/components/MaintainerCard.tsx b/src/components/MaintainerCard.tsx index 7ab6f1994..a3c2ac709 100644 --- a/src/components/MaintainerCard.tsx +++ b/src/components/MaintainerCard.tsx @@ -1,4 +1,4 @@ -import { Library } from '~/libraries' +import { Library, Framework, frameworkOptions } from '~/libraries' import { getRoleInLibrary, Maintainer } from '~/libraries/maintainers' function RoleBadge({ role, libraryId }: { role: string; libraryId: string }) { @@ -24,6 +24,19 @@ function RoleBadge({ role, libraryId }: { role: string; libraryId: string }) { return {role} } +function FrameworkChip({ framework }: { framework: Framework }) { + const frameworkOption = frameworkOptions.find((f) => f.value === framework) + const bgColor = frameworkOption?.color || 'bg-gray-500' + + return ( + + {frameworkOption?.label || framework} + + ) +} + interface MaintainerCardProps { maintainer: Maintainer libraryId: Library['id'] @@ -47,38 +60,80 @@ export function MaintainerCard({ maintainer, libraryId }: MaintainerCardProps) { objectFit: 'cover', }} /> - - - - - - {maintainer.name} - + + + + {maintainer.name} + {maintainer.frameworkExpertise && + maintainer.frameworkExpertise.length > 0 && ( + + {maintainer.frameworkExpertise.map((framework) => ( + + ))} + + )} + {maintainer.specialties && maintainer.specialties.length > 0 && ( + + {maintainer.specialties.map((specialty) => ( + + {specialty} + + ))} + + )} - - + + + + + {maintainer.name} + + + + e.stopPropagation()} + > + - @{maintainer.github} - - - - {maintainer.specialties?.map((specialty: string) => ( - + {maintainer.social?.twitter && ( + e.stopPropagation()} + > + + + + + )} + {maintainer.social?.website && ( + e.stopPropagation()} > - {specialty} - - ))} - + + + + + )} + ) From 47453057811c5791dbd66d08fea2e4b11ac40100 Mon Sep 17 00:00:00 2001 From: Kevin Van Cott Date: Wed, 4 Jun 2025 14:16:01 -0500 Subject: [PATCH 12/20] update social links --- src/libraries/maintainers.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/libraries/maintainers.ts b/src/libraries/maintainers.ts index c178a4ef7..3df1a7066 100644 --- a/src/libraries/maintainers.ts +++ b/src/libraries/maintainers.ts @@ -38,6 +38,11 @@ export const allMaintainers: Maintainer[] = [ ], frameworkExpertise: ['react', 'solid'], specialties: ['Architecture', 'Core API', 'Documentation'], + social: { + twitter: 'https://x.com/tannerlinsley', + bluesky: 'https://bsky.app/profile/tannerlinsley.com', + website: 'https://tannerlinsley.com', + }, }, { name: 'Dominik Dorfmeister', @@ -62,6 +67,11 @@ export const allMaintainers: Maintainer[] = [ maintainerOf: ['store'], frameworkExpertise: ['react', 'solid', 'vue', 'angular'], specialties: ['Forms', 'Validation', 'State Management'], + social: { + twitter: 'https://x.com/crutchcorn', + bluesky: 'https://bsky.app/profile/crutchcorn.dev', + website: 'https://playfulprogramming.com/people/crutchcorn', + }, }, { name: 'Manual Schiller', @@ -83,6 +93,11 @@ export const allMaintainers: Maintainer[] = [ consultantOf: ['query'], frameworkExpertise: ['react', 'solid', 'svelte'], specialties: ['Tables', 'Data Grids', 'Dashboards'], + social: { + twitter: 'https://x.com/kevinvancott', + bluesky: 'https://bsky.app/profile/kevinvancott.dev', + website: 'https://kevinvancott.dev', + }, }, { name: 'Sean Cassiere', From bb12aba09ff66faede2f52e4161f648781451f43 Mon Sep 17 00:00:00 2001 From: Kevin Van Cott Date: Wed, 4 Jun 2025 18:04:58 -0500 Subject: [PATCH 13/20] add core contributors to home page --- src/components/ContributorsWall.tsx | 22 ++- src/components/MaintainerCard.tsx | 83 +++++++++-- src/libraries/index.tsx | 13 +- src/libraries/maintainers.ts | 58 ++++++++ src/routes/_libraries/index.tsx | 13 ++ src/routes/_libraries/route.tsx | 217 ++++++++++++++-------------- 6 files changed, 279 insertions(+), 127 deletions(-) diff --git a/src/components/ContributorsWall.tsx b/src/components/ContributorsWall.tsx index eb307f6df..920c9bec4 100644 --- a/src/components/ContributorsWall.tsx +++ b/src/components/ContributorsWall.tsx @@ -10,12 +10,30 @@ export function ContributorsWall({ library }: { library: Library }) { > - Powered by contrib.rocks + Powered by{' '} + + contrib.rocks + + + + + View all contributors on GitHub + ) diff --git a/src/components/MaintainerCard.tsx b/src/components/MaintainerCard.tsx index a3c2ac709..028dc4ba9 100644 --- a/src/components/MaintainerCard.tsx +++ b/src/components/MaintainerCard.tsx @@ -1,7 +1,12 @@ import { Library, Framework, frameworkOptions } from '~/libraries' -import { getRoleInLibrary, Maintainer } from '~/libraries/maintainers' +import { + getRoleInLibrary, + Maintainer, + getPersonsMaintainerOf, +} from '~/libraries/maintainers' +import { useState } from 'react' -function RoleBadge({ role, libraryId }: { role: string; libraryId: string }) { +function RoleBadge({ role }: { role: string }) { const isCreator = role.toLowerCase().includes('creator') const isMaintainer = role.toLowerCase().includes('maintainer') @@ -37,12 +42,27 @@ function FrameworkChip({ framework }: { framework: Framework }) { ) } +function LibraryBadge({ library }: { library: Library }) { + return ( + + {library.name} + + ) +} + interface MaintainerCardProps { maintainer: Maintainer - libraryId: Library['id'] + libraryId?: Library['id'] } export function MaintainerCard({ maintainer, libraryId }: MaintainerCardProps) { + const libraries = getPersonsMaintainerOf(maintainer) + const [showAllLibraries, setShowAllLibraries] = useState(false) + return ( + {!libraryId && libraries.length > 0 && ( + + {libraries + .slice(0, showAllLibraries ? undefined : 2) + .map((library) => ( + + ))} + {!showAllLibraries && libraries.length > 2 && ( + { + e.preventDefault() + e.stopPropagation() + setShowAllLibraries(true) + }} + className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 transition-colors" + > + +{libraries.length - 3} more + + )} + + )} {maintainer.name} - + {libraryId && ( + + )} - + e.stopPropagation()} > - + {maintainer.social?.twitter && ( e.stopPropagation()} > - - + + )} + {maintainer.social?.bluesky && ( + e.stopPropagation()} + > + 🦋 + + )} {maintainer.social?.website && ( e.stopPropagation()} > - + diff --git a/src/libraries/index.tsx b/src/libraries/index.tsx index da0f5a1f4..c9e49ad90 100644 --- a/src/libraries/index.tsx +++ b/src/libraries/index.tsx @@ -60,7 +60,7 @@ export type Library = { | 'create-tsrouter-app' name: string cardStyles: string - to: string + to?: string tagline: string description: string ogImage?: string @@ -90,6 +90,7 @@ export type Library = { }[] docsRoot?: string embedEditor?: 'codesandbox' | 'stackblitz' + visible?: boolean } export type LibraryMenuItem = { @@ -110,6 +111,16 @@ export const libraries = [ rangerProject, dbProject, configProject, + { + id: 'react-charts', + name: 'React Charts', + repo: 'tanstack/react-charts', + } as Library, + { + id: 'create-tsrouter-app', + name: 'Create TS Router App', + repo: 'tanstack/create-tsrouter-app', + } as Library, ] satisfies Library[] export const librariesByGroup = { diff --git a/src/libraries/maintainers.ts b/src/libraries/maintainers.ts index 3df1a7066..b951a08de 100644 --- a/src/libraries/maintainers.ts +++ b/src/libraries/maintainers.ts @@ -34,6 +34,7 @@ export const allMaintainers: Maintainer[] = [ 'virtual', 'ranger', 'store', + 'pacer', 'react-charts', ], frameworkExpertise: ['react', 'solid'], @@ -208,6 +209,63 @@ export const allMaintainers: Maintainer[] = [ website: 'https://www.linkedin.com/in/jonghyeonko', }, }, + { + name: 'Riccardo Perra', + avatar: + 'https://cdn.bsky.app/img/avatar/plain/did:plc:gtnigsmgu7jyrc4tnkvn62qw/bafkreiceysbj4o6jrbbniudtwj3tcsns6rvwcxyjsqiaumeojurwbkki5a@jpeg', + github: 'riccardoperra', + contributorOf: ['table'], + frameworkExpertise: ['angular', 'solid'], + specialties: [], + social: { + twitter: 'https://x.com/riccardoperra0', + bluesky: 'https://bsky.app/profile/riccardoperra.bsky.social', + website: 'https://riccardoperra.com', + }, + }, + { + name: 'Birk Skyum', + avatar: 'https://github.com/birkskyum.png', + github: 'birkskyum', + maintainerOf: ['start'], + frameworkExpertise: ['solid'], + specialties: [], + social: { + twitter: 'https://x.com/birkskyum', + bluesky: 'https://bsky.app/profile/bskyum.bsky.social', + }, + }, + { + name: 'Arnoud de Vries', + avatar: 'https://github.com/arnoud-dv.png', + github: 'arnoud-dv', + maintainerOf: ['query'], + frameworkExpertise: ['angular', 'react'], + specialties: [ + 'Architecture', + 'Developer Experience', + 'TypeScript', + 'Reactivity', + ], + social: { + twitter: 'https://x.com/Arnoud_dv', + bluesky: 'https://bsky.app/profile/arnoud.dev', + website: 'https://www.linkedin.com/in/arnouddv/', + }, + }, + { + name: 'Fülöp Kovács', + isCoreMaintainer: false, + avatar: 'https://github.com/fulopkovacs.png', + github: 'fulopkovacs', + maintainerOf: ['form'], + frameworkExpertise: ['react'], + social: { + website: 'https://fulop.dev/', + twitter: 'https://x.com/notacheetah', + bluesky: 'https://bsky.app/profile/notacheetah.bsky.social', + }, + }, ] export const coreMaintainers = allMaintainers.filter( diff --git a/src/routes/_libraries/index.tsx b/src/routes/_libraries/index.tsx index d613a6807..aef9140cf 100644 --- a/src/routes/_libraries/index.tsx +++ b/src/routes/_libraries/index.tsx @@ -15,6 +15,8 @@ import splashLightImg from '~/images/splash-light.png' import splashDarkImg from '~/images/splash-dark.png' import { GadFooter } from '~/components/GoogleScripts' import LandingPageGad from '~/components/LandingPageGad' +import { MaintainerCard } from '~/components/MaintainerCard' +import { coreMaintainers } from '~/libraries/maintainers' export const textColors = [ `text-rose-500`, @@ -382,6 +384,17 @@ function Index() { + + Core Maintainers + + {coreMaintainers.map((maintainer) => ( + + ))} + + + diff --git a/src/routes/_libraries/route.tsx b/src/routes/_libraries/route.tsx index aa796b3e5..923b88a86 100644 --- a/src/routes/_libraries/route.tsx +++ b/src/routes/_libraries/route.tsx @@ -34,7 +34,7 @@ function LibrariesLayout() { const activeLibrary = useLocation({ select: (location) => { return libraries.find((library) => { - return location.pathname.startsWith(library.to) + return location.pathname.startsWith(library.to!) }) }, }) @@ -44,124 +44,123 @@ function LibrariesLayout() { const items = ( <> - {sortBy(libraries, (d) => !d.name.includes('TanStack')).map( - (library, i) => { - const [prefix, name] = library.name.split(' ') + {sortBy( + libraries.filter((d) => d.to), + (d) => !d.name.includes('TanStack') + ).map((library, i) => { + const [prefix, name] = library.name.split(' ') - return ( - - {library.to.startsWith('http') ? ( - - - - {prefix} - {' '} - {name} - - - ) : ( - - { - detailsRef.current.removeAttribute('open') - }} - > - {(props) => { - return ( - + {library.to?.startsWith('http') ? ( + + + + {prefix} + {' '} + {name} + + + ) : ( + + { + detailsRef.current.removeAttribute('open') + }} + > + {(props) => { + return ( + + + {prefix} + {' '} + + {name} + + + {library.badge ? ( + - - {prefix} - {' '} - - {name} - + {library.badge} - {library.badge ? ( - - {library.badge} - - ) : null} - - ) + ) : null} + + ) + }} + + + {library.menu?.map((item, i) => { + return ( + + {item.icon} + {item.label} + + ) + })} + - - {library.menu?.map((item, i) => { - return ( - - {item.icon} - {item.label} - - ) - })} - - - Contributors - - + + Contributors + - )} - - ) - } - )} + + )} + + ) + })} From 7406ce5448d7ea849f67babf06407c1ef8a6e606 Mon Sep 17 00:00:00 2001 From: SeanCassiere <33615041+SeanCassiere@users.noreply.github.com> Date: Thu, 5 Jun 2025 12:53:27 +1200 Subject: [PATCH 14/20] add details for Manuel --- src/libraries/maintainers.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libraries/maintainers.ts b/src/libraries/maintainers.ts index b951a08de..631e749f0 100644 --- a/src/libraries/maintainers.ts +++ b/src/libraries/maintainers.ts @@ -75,13 +75,17 @@ export const allMaintainers: Maintainer[] = [ }, }, { - name: 'Manual Schiller', + name: 'Manuel Schiller', isCoreMaintainer: true, avatar: 'https://github.com/schiller-manuel.png', github: 'schiller-manuel', maintainerOf: ['start', 'router'], frameworkExpertise: ['react'], - specialties: [], + specialties: ['Architecture', 'Core API', 'Documentation'], + social: { + twitter: 'https://x.com/schanuelmiller', + bluesky: 'https://bsky.app/profile/manuelschiller.bsky.social', + }, }, { name: 'Kevin Van Cott', From 4377f6c52d9d274f74c6ffb89a062334acfab242 Mon Sep 17 00:00:00 2001 From: SeanCassiere <33615041+SeanCassiere@users.noreply.github.com> Date: Thu, 5 Jun 2025 12:54:32 +1200 Subject: [PATCH 15/20] add details for Sean --- src/libraries/maintainers.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libraries/maintainers.ts b/src/libraries/maintainers.ts index 631e749f0..c860c1087 100644 --- a/src/libraries/maintainers.ts +++ b/src/libraries/maintainers.ts @@ -111,7 +111,12 @@ export const allMaintainers: Maintainer[] = [ github: 'seancassiere', maintainerOf: ['start', 'router'], frameworkExpertise: ['react'], - specialties: [], + specialties: ['Architecture', 'Core API', 'Documentation'], + social: { + twitter: 'https://x.com/seancassiere', + bluesky: 'https://bsky.app/profile/seancassiere.com', + website: 'https://seancassiere.com', + }, }, { name: 'Chris Horobin', From 9b74a3e70c4e697073ce99e298005a6b95615baa Mon Sep 17 00:00:00 2001 From: SeanCassiere <33615041+SeanCassiere@users.noreply.github.com> Date: Thu, 5 Jun 2025 12:55:33 +1200 Subject: [PATCH 16/20] add details for TypeChris --- src/libraries/maintainers.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libraries/maintainers.ts b/src/libraries/maintainers.ts index c860c1087..2dd504adc 100644 --- a/src/libraries/maintainers.ts +++ b/src/libraries/maintainers.ts @@ -123,9 +123,13 @@ export const allMaintainers: Maintainer[] = [ isCoreMaintainer: true, avatar: 'https://github.com/chorobin.png', github: 'chorobin', - maintainerOf: ['router'], + maintainerOf: ['start', 'router'], frameworkExpertise: ['react'], specialties: ['TypeScript'], + social: { + twitter: 'https://x.com/c_horobin', + bluesky: 'https://bsky.app/profile/chorobin.bsky.social', + }, }, { name: 'Damian Pieczynski', From a8a9d17768458bdfd8d5b7e9cb3f937f1f655f16 Mon Sep 17 00:00:00 2001 From: SeanCassiere <33615041+SeanCassiere@users.noreply.github.com> Date: Thu, 5 Jun 2025 13:04:58 +1200 Subject: [PATCH 17/20] fix the bluesky links for Dominik --- src/libraries/maintainers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/maintainers.ts b/src/libraries/maintainers.ts index 2dd504adc..b56f44dab 100644 --- a/src/libraries/maintainers.ts +++ b/src/libraries/maintainers.ts @@ -55,7 +55,7 @@ export const allMaintainers: Maintainer[] = [ frameworkExpertise: ['react'], specialties: ['Core API', 'TypeScript', 'Documentation'], social: { - bluesky: '@tkdodo.eu', + bluesky: 'https://bsky.app/profile/tkdodo.eu', website: 'https://tkdodo.eu', }, }, From 4c2f1c716ef4159bbfeec93471a6009f5fc4b644 Mon Sep 17 00:00:00 2001 From: Kevin Van Cott Date: Wed, 4 Jun 2025 21:07:22 -0500 Subject: [PATCH 18/20] Improve maintainer card pill designs --- src/components/MaintainerCard.tsx | 92 +++++++++++++++---- .../$libraryId/$version.docs.contributors.tsx | 4 +- src/routes/_libraries/index.tsx | 4 +- 3 files changed, 75 insertions(+), 25 deletions(-) diff --git a/src/components/MaintainerCard.tsx b/src/components/MaintainerCard.tsx index 028dc4ba9..a1adbc2ac 100644 --- a/src/components/MaintainerCard.tsx +++ b/src/components/MaintainerCard.tsx @@ -32,24 +32,52 @@ function RoleBadge({ role }: { role: string }) { function FrameworkChip({ framework }: { framework: Framework }) { const frameworkOption = frameworkOptions.find((f) => f.value === framework) const bgColor = frameworkOption?.color || 'bg-gray-500' - return ( + + + {frameworkOption?.label || framework} ) } +function SpecialtyChip({ specialty }: { specialty: string }) { + return ( + + + + + {specialty} + + ) +} + function LibraryBadge({ library }: { library: Library }) { return ( - {library.name} + {library.name.replace('TanStack', '🌴')} ) } @@ -69,10 +97,11 @@ export function MaintainerCard({ maintainer, libraryId }: MaintainerCardProps) { className="group bg-white dark:bg-gray-800 rounded-lg overflow-hidden shadow-lg" target="_blank" rel="noopener noreferrer" + aria-label={`View ${maintainer.name}'s GitHub profile`} > - {maintainer.name} {maintainer.frameworkExpertise && maintainer.frameworkExpertise.length > 0 && ( @@ -97,12 +125,7 @@ export function MaintainerCard({ maintainer, libraryId }: MaintainerCardProps) { {maintainer.specialties && maintainer.specialties.length > 0 && ( {maintainer.specialties.map((specialty) => ( - - {specialty} - + ))} )} @@ -124,15 +147,23 @@ export function MaintainerCard({ maintainer, libraryId }: MaintainerCardProps) { e.stopPropagation() setShowAllLibraries(true) }} - className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 transition-colors" + className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 transition-colors focus:outline-none focus:ring-2 focus:ring-blue-400" + aria-label={`Show ${libraries.length - 2} more libraries`} + tabIndex={0} + type="button" > - +{libraries.length - 3} more + +{libraries.length - 2} more )} )} - {maintainer.name} + + {maintainer.name} + {libraryId && ( )} @@ -143,9 +174,15 @@ export function MaintainerCard({ maintainer, libraryId }: MaintainerCardProps) { className="hover:text-gray-700 dark:hover:text-gray-200 transition-colors p-2 -m-2 hover:grayscale-0" target="_blank" rel="noopener noreferrer" + aria-label="GitHub profile" onClick={(e) => e.stopPropagation()} > - + @@ -155,9 +192,15 @@ export function MaintainerCard({ maintainer, libraryId }: MaintainerCardProps) { className="hover:text-gray-700 dark:hover:text-gray-200 transition-colors p-2 -m-2 hover:grayscale-0" target="_blank" rel="noopener noreferrer" + aria-label="Twitter profile" onClick={(e) => e.stopPropagation()} > - + @@ -168,9 +211,12 @@ export function MaintainerCard({ maintainer, libraryId }: MaintainerCardProps) { className="hover:text-gray-700 dark:hover:text-gray-200 transition-colors p-2 -m-2 hover:grayscale-0" target="_blank" rel="noopener noreferrer" + aria-label="Bluesky profile" onClick={(e) => e.stopPropagation()} > - 🦋 + + 🦋 + )} {maintainer.social?.website && ( @@ -179,9 +225,15 @@ export function MaintainerCard({ maintainer, libraryId }: MaintainerCardProps) { className="hover:text-gray-700 dark:hover:text-gray-200 transition-colors p-2 -m-2 hover:grayscale-0" target="_blank" rel="noopener noreferrer" + aria-label="Personal website" onClick={(e) => e.stopPropagation()} > - + diff --git a/src/routes/$libraryId/$version.docs.contributors.tsx b/src/routes/$libraryId/$version.docs.contributors.tsx index d2b78c648..40c2d1f56 100644 --- a/src/routes/$libraryId/$version.docs.contributors.tsx +++ b/src/routes/$libraryId/$version.docs.contributors.tsx @@ -31,7 +31,7 @@ function RouteComponent() { {library.name} Maintainers and Contributors - + {libraryContributors.map((maintainer) => ( - All Contributors + All-Time Contributors diff --git a/src/routes/_libraries/index.tsx b/src/routes/_libraries/index.tsx index aef9140cf..deba766b8 100644 --- a/src/routes/_libraries/index.tsx +++ b/src/routes/_libraries/index.tsx @@ -386,9 +386,7 @@ function Index() { Core Maintainers - + {coreMaintainers.map((maintainer) => ( ))} From 3daca924699a4ec00e3d51f667a14e7e2a5b4478 Mon Sep 17 00:00:00 2001 From: Kevin Van Cott Date: Thu, 5 Jun 2025 08:35:28 -0500 Subject: [PATCH 19/20] add more maintainers and fix card pill alignments --- src/components/MaintainerCard.tsx | 78 ++++++++++++++++++++----------- src/libraries/maintainers.ts | 48 +++++++++++++++++-- 2 files changed, 96 insertions(+), 30 deletions(-) diff --git a/src/components/MaintainerCard.tsx b/src/components/MaintainerCard.tsx index a1adbc2ac..5a3ab262d 100644 --- a/src/components/MaintainerCard.tsx +++ b/src/components/MaintainerCard.tsx @@ -6,9 +6,17 @@ import { } from '~/libraries/maintainers' import { useState } from 'react' -function RoleBadge({ role }: { role: string }) { +function RoleBadge({ + maintainer, + libraryId, +}: { + maintainer: Maintainer + libraryId?: Library['id'] +}) { + const role = libraryId ? getRoleInLibrary(maintainer, libraryId) : '' const isCreator = role.toLowerCase().includes('creator') const isMaintainer = role.toLowerCase().includes('maintainer') + const isCoreMaintainer = isMaintainer && maintainer.isCoreMaintainer if (isCreator) { return ( @@ -20,7 +28,13 @@ function RoleBadge({ role }: { role: string }) { if (isMaintainer) { return ( - + {role} ) @@ -71,14 +85,18 @@ function SpecialtyChip({ specialty }: { specialty: string }) { function LibraryBadge({ library }: { library: Library }) { return ( - e.stopPropagation()} + title={`View all contributors for ${library.name}`} > {library.name.replace('TanStack', '🌴')} - + ) } @@ -92,14 +110,18 @@ export function MaintainerCard({ maintainer, libraryId }: MaintainerCardProps) { const [showAllLibraries, setShowAllLibraries] = useState(false) return ( - - + - + + + + {maintainer.name} + + + {libraryId && ( + + )} + + {!libraryId && libraries.length > 0 && ( - + {libraries .slice(0, showAllLibraries ? undefined : 2) .map((library) => ( @@ -157,18 +192,7 @@ export function MaintainerCard({ maintainer, libraryId }: MaintainerCardProps) { )} )} - - - {maintainer.name} - - {libraryId && ( - - )} - - + - + ) } diff --git a/src/libraries/maintainers.ts b/src/libraries/maintainers.ts index b56f44dab..d7564bf8f 100644 --- a/src/libraries/maintainers.ts +++ b/src/libraries/maintainers.ts @@ -65,7 +65,7 @@ export const allMaintainers: Maintainer[] = [ avatar: 'https://github.com/crutchcorn.png', github: 'crutchcorn', creatorOf: ['form'], - maintainerOf: ['store'], + maintainerOf: ['store', 'config'], frameworkExpertise: ['react', 'solid', 'vue', 'angular'], specialties: ['Forms', 'Validation', 'State Management'], social: { @@ -227,7 +227,7 @@ export const allMaintainers: Maintainer[] = [ avatar: 'https://cdn.bsky.app/img/avatar/plain/did:plc:gtnigsmgu7jyrc4tnkvn62qw/bafkreiceysbj4o6jrbbniudtwj3tcsns6rvwcxyjsqiaumeojurwbkki5a@jpeg', github: 'riccardoperra', - contributorOf: ['table'], + maintainerOf: ['table'], frameworkExpertise: ['angular', 'solid'], specialties: [], social: { @@ -241,6 +241,7 @@ export const allMaintainers: Maintainer[] = [ avatar: 'https://github.com/birkskyum.png', github: 'birkskyum', maintainerOf: ['start'], + contributorOf: ['pacer'], frameworkExpertise: ['solid'], specialties: [], social: { @@ -268,7 +269,6 @@ export const allMaintainers: Maintainer[] = [ }, { name: 'Fülöp Kovács', - isCoreMaintainer: false, avatar: 'https://github.com/fulopkovacs.png', github: 'fulopkovacs', maintainerOf: ['form'], @@ -279,6 +279,48 @@ export const allMaintainers: Maintainer[] = [ bluesky: 'https://bsky.app/profile/notacheetah.bsky.social', }, }, + { + name: 'Aryan Deora', + avatar: 'https://github.com/ardeora.png', + github: 'ardeora', + maintainerOf: ['query'], + frameworkExpertise: ['solid'], + specialties: ['Dev Tools'], + social: { + twitter: 'https://x.com/aryan__deora', + website: 'https://www.aryandeora.com/', + }, + }, + { + name: 'Mokshit Jain', + avatar: 'https://github.com/Mokshit06.png', + contributorOf: ['table'], + frameworkExpertise: ['svelte', 'solid', 'vue'], + github: 'Mokshit06', + social: { + twitter: 'https://x.com/mokshit06', + website: 'https://mokshitjain.co', + }, + }, + { + name: 'Walker Lockard', + github: 'walker-tx', + avatar: 'https://github.com/walker-tx.png', + contributorOf: ['table'], + frameworkExpertise: ['svelte', 'react'], + social: { + twitter: 'https://x.com/walker_lockard', + website: 'https://walker.dev', + }, + }, + { + name: 'Tom', + github: 'tombuntus', + avatar: 'https://github.com/tombuntus.png', + contributorOf: ['table'], + frameworkExpertise: ['react'], + social: {}, + }, ] export const coreMaintainers = allMaintainers.filter( From 12b7250b4ec3107931920cdecc556acb36bd3140 Mon Sep 17 00:00:00 2001 From: Kevin Van Cott Date: Thu, 5 Jun 2025 08:39:32 -0500 Subject: [PATCH 20/20] fix tanstack pill links when they don't exist --- src/components/MaintainerCard.tsx | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/components/MaintainerCard.tsx b/src/components/MaintainerCard.tsx index 5a3ab262d..f727f2869 100644 --- a/src/components/MaintainerCard.tsx +++ b/src/components/MaintainerCard.tsx @@ -84,19 +84,32 @@ function SpecialtyChip({ specialty }: { specialty: string }) { } function LibraryBadge({ library }: { library: Library }) { + if (library.to) { + return ( + e.stopPropagation()} + title={`View all contributors for ${library.name}`} + > + {library.name.replace('TanStack', '🌴')} + + ) + } return ( - e.stopPropagation()} title={`View all contributors for ${library.name}`} > {library.name.replace('TanStack', '🌴')} - + ) }
- +