Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/components/LibraryCard.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
import { Link } from '@tanstack/react-router'
import { Link, useParams } from '@tanstack/react-router'
import { Library } from '~/libraries'
import { frameworkOptions } from '~/libraries/frameworks'
import { twMerge } from 'tailwind-merge'

export default function LibraryCard({
library,
index = 0,
isGeneric = false,
namePrefix,
}: {
library: Library
index?: number
isGeneric?: boolean
namePrefix?: string
}) {
const isExternal = library.to?.startsWith('http')
const Component = isExternal ? 'a' : Link
const props = isExternal
? { href: library.to, target: '_blank', rel: 'noopener noreferrer' }
: { to: library.to ?? '#' }
const params = useParams({ strict: false })
const frameworkPrefix =
namePrefix ??
frameworkOptions.find((framework) => framework.value === params.framework)
?.label

const hasTanStackPrefix = library.name.startsWith('TanStack ')
const nameWithoutPrefix = library.name.replace('TanStack ', '')
const displayName = frameworkPrefix
? `${frameworkPrefix}-${nameWithoutPrefix}`
: nameWithoutPrefix

return (
<Component
Expand Down Expand Up @@ -82,7 +93,7 @@ export default function LibraryCard({
: 'text-current'
}
>
{nameWithoutPrefix}
{displayName}
</span>
</>
) : (
Expand All @@ -93,7 +104,7 @@ export default function LibraryCard({
: 'text-current'
}
>
{nameWithoutPrefix}
{displayName}
</span>
)}
</div>
Expand Down
1 change: 1 addition & 0 deletions src/images/alpine-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 15 additions & 7 deletions src/libraries/frameworks.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import alpineLogo from '../images/alpine-logo.svg'
import angularLogo from '../images/angular-logo.svg'
import jsLogo from '../images/js-logo.svg'
import litLogo from '../images/lit-logo.svg'
Expand Down Expand Up @@ -45,13 +46,6 @@ export const frameworkOptions = [
color: 'bg-blue-600',
fontColor: 'text-blue-600',
},
{
label: 'Lit',
value: 'lit',
logo: litLogo,
color: 'bg-emerald-500',
fontColor: 'text-emerald-500',
},
{
label: 'Svelte',
value: 'svelte',
Expand All @@ -66,6 +60,20 @@ export const frameworkOptions = [
color: 'bg-indigo-500',
fontColor: 'text-indigo-500',
},
{
label: 'Lit',
value: 'lit',
logo: litLogo,
color: 'bg-emerald-500',
fontColor: 'text-emerald-500',
},
{
label: 'Alpine',
value: 'alpine',
logo: alpineLogo,
color: 'bg-slate-500',
fontColor: 'text-slate-500',
},
{
label: 'Vanilla',
value: 'vanilla',
Expand Down
5 changes: 3 additions & 2 deletions src/libraries/libraries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,12 +321,13 @@ export const table: LibrarySlim = {
repo: 'tanstack/table',
frameworks: [
'angular',
'lit',
'qwik',
'react',
'solid',
'svelte',
'vue',
'qwik',
'lit',
'alpine',
'vanilla',
Comment thread
KevinVandy marked this conversation as resolved.
],
latestVersion: 'v8',
Expand Down
1 change: 1 addition & 0 deletions src/libraries/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from 'react'

export type Framework =
| 'angular'
| 'alpine'
| 'lit'
| 'preact'
| 'qwik'
Expand Down
21 changes: 21 additions & 0 deletions src/routeTree.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import { Route as PartnersPartnerRouteImport } from './routes/partners.$partner'
import { Route as OauthTokenRouteImport } from './routes/oauth/token'
import { Route as OauthRegisterRouteImport } from './routes/oauth/register'
import { Route as OauthAuthorizeRouteImport } from './routes/oauth/authorize'
import { Route as LibrariesFrameworkRouteImport } from './routes/libraries_.$framework'
import { Route as BuilderDocsRouteImport } from './routes/builder.docs'
import { Route as BlogSplatRouteImport } from './routes/blog.$'
import { Route as AuthSignoutRouteImport } from './routes/auth/signout'
Expand Down Expand Up @@ -390,6 +391,11 @@ const OauthAuthorizeRoute = OauthAuthorizeRouteImport.update({
path: '/oauth/authorize',
getParentRoute: () => rootRouteImport,
} as any)
const LibrariesFrameworkRoute = LibrariesFrameworkRouteImport.update({
id: '/libraries_/$framework',
path: '/libraries/$framework',
getParentRoute: () => rootRouteImport,
} as any)
const BuilderDocsRoute = BuilderDocsRouteImport.update({
id: '/docs',
path: '/docs',
Expand Down Expand Up @@ -925,6 +931,7 @@ export interface FileRoutesByFullPath {
'/auth/signout': typeof AuthSignoutRoute
'/blog/$': typeof BlogSplatRoute
'/builder/docs': typeof BuilderDocsRoute
'/libraries/$framework': typeof LibrariesFrameworkRoute
'/oauth/authorize': typeof OauthAuthorizeRoute
'/oauth/register': typeof OauthRegisterRoute
'/oauth/token': typeof OauthTokenRoute
Expand Down Expand Up @@ -1059,6 +1066,7 @@ export interface FileRoutesByTo {
'/auth/signout': typeof AuthSignoutRoute
'/blog/$': typeof BlogSplatRoute
'/builder/docs': typeof BuilderDocsRoute
'/libraries/$framework': typeof LibrariesFrameworkRoute
'/oauth/authorize': typeof OauthAuthorizeRoute
'/oauth/register': typeof OauthRegisterRoute
'/oauth/token': typeof OauthTokenRoute
Expand Down Expand Up @@ -1200,6 +1208,7 @@ export interface FileRoutesById {
'/auth/signout': typeof AuthSignoutRoute
'/blog/$': typeof BlogSplatRoute
'/builder/docs': typeof BuilderDocsRoute
'/libraries_/$framework': typeof LibrariesFrameworkRoute
'/oauth/authorize': typeof OauthAuthorizeRoute
'/oauth/register': typeof OauthRegisterRoute
'/oauth/token': typeof OauthTokenRoute
Expand Down Expand Up @@ -1344,6 +1353,7 @@ export interface FileRouteTypes {
| '/auth/signout'
| '/blog/$'
| '/builder/docs'
| '/libraries/$framework'
| '/oauth/authorize'
| '/oauth/register'
| '/oauth/token'
Expand Down Expand Up @@ -1478,6 +1488,7 @@ export interface FileRouteTypes {
| '/auth/signout'
| '/blog/$'
| '/builder/docs'
| '/libraries/$framework'
| '/oauth/authorize'
| '/oauth/register'
| '/oauth/token'
Expand Down Expand Up @@ -1618,6 +1629,7 @@ export interface FileRouteTypes {
| '/auth/signout'
| '/blog/$'
| '/builder/docs'
| '/libraries_/$framework'
| '/oauth/authorize'
| '/oauth/register'
| '/oauth/token'
Expand Down Expand Up @@ -1747,6 +1759,7 @@ export interface RootRouteChildren {
AuthCliRoute: typeof AuthCliRoute
AuthPopupSuccessRoute: typeof AuthPopupSuccessRoute
AuthSignoutRoute: typeof AuthSignoutRoute
LibrariesFrameworkRoute: typeof LibrariesFrameworkRoute
OauthAuthorizeRoute: typeof OauthAuthorizeRoute
OauthRegisterRoute: typeof OauthRegisterRoute
OauthTokenRoute: typeof OauthTokenRoute
Expand Down Expand Up @@ -2139,6 +2152,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof OauthAuthorizeRouteImport
parentRoute: typeof rootRouteImport
}
'/libraries_/$framework': {
id: '/libraries_/$framework'
path: '/libraries/$framework'
fullPath: '/libraries/$framework'
preLoaderRoute: typeof LibrariesFrameworkRouteImport
parentRoute: typeof rootRouteImport
}
'/builder/docs': {
id: '/builder/docs'
path: '/docs'
Expand Down Expand Up @@ -3041,6 +3061,7 @@ const rootRouteChildren: RootRouteChildren = {
AuthCliRoute: AuthCliRoute,
AuthPopupSuccessRoute: AuthPopupSuccessRoute,
AuthSignoutRoute: AuthSignoutRoute,
LibrariesFrameworkRoute: LibrariesFrameworkRoute,
OauthAuthorizeRoute: OauthAuthorizeRoute,
OauthRegisterRoute: OauthRegisterRoute,
OauthTokenRoute: OauthTokenRoute,
Expand Down
43 changes: 43 additions & 0 deletions src/routes/-libraries-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { libraries, type Framework, type LibrarySlim } from '~/libraries'

export function getVisibleLibraries() {
return libraries.filter((library) => library.to && library.visible !== false)
}

export function orderLibrariesForBrowse<TLibrary extends LibrarySlim>(
allLibraries: Array<TLibrary>,
) {
const others = allLibraries.filter(
(library) =>
library.id !== 'ranger' &&
library.id !== 'config' &&
library.id !== 'react-charts',
)
const ranger = allLibraries.filter((library) => library.id === 'ranger')
const config = allLibraries.filter((library) => library.id === 'config')

const devtoolsIndex = others.findIndex((library) => library.id === 'devtools')

if (devtoolsIndex === -1) {
return [...others, ...config, ...ranger]
}

return [
...others.slice(0, devtoolsIndex + 1),
...config,
...others.slice(devtoolsIndex + 1),
...ranger,
]
}

export function getFrameworkLibraryCounts(allLibraries: Array<LibrarySlim>) {
const counts = {} as Partial<Record<Framework, number>>

for (const library of allLibraries) {
for (const framework of library.frameworks) {
counts[framework] = (counts[framework] ?? 0) + 1
}
}

return counts
}
61 changes: 44 additions & 17 deletions src/routes/libraries.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { createFileRoute } from '@tanstack/react-router'
import { Link, createFileRoute } from '@tanstack/react-router'
import * as React from 'react'
import { libraries, Library } from '~/libraries'
import { type Library } from '~/libraries'
import { frameworkOptions } from '~/libraries/frameworks'
import { reactChartsProject } from '~/libraries/react-charts'
import LibraryCard from '~/components/LibraryCard'
import {
getFrameworkLibraryCounts,
getVisibleLibraries,
orderLibrariesForBrowse,
} from './-libraries-utils'

export const Route = createFileRoute('/libraries')({
component: LibrariesPage,
Expand All @@ -20,22 +26,12 @@ export const Route = createFileRoute('/libraries')({
})

function LibrariesPage() {
const allLibraries = libraries.filter((d) => d.to && d.visible !== false)
const others = allLibraries.filter(
(l) => l.id !== 'ranger' && l.id !== 'config' && l.id !== 'react-charts',
const allLibraries = getVisibleLibraries()
const ordered = orderLibrariesForBrowse(allLibraries)
const frameworkCounts = getFrameworkLibraryCounts(allLibraries)
const frameworksWithLibraries = frameworkOptions.filter(
(framework) => (frameworkCounts[framework.value] ?? 0) > 0,
)
const ranger = allLibraries.filter((l) => l.id === 'ranger')
const config = allLibraries.filter((l) => l.id === 'config')

// Find devtools index in others to insert config after it
const devtoolsIndex = others.findIndex((l) => l.id === 'devtools')
const ordered = [
...others.slice(0, devtoolsIndex + 1),
...config,
...others.slice(devtoolsIndex + 1),
...ranger,
]

const deprecatedLibraries = [reactChartsProject]

return (
Expand All @@ -45,6 +41,37 @@ function LibrariesPage() {
Browse all TanStack libraries.
</p>

<section className="mt-8">
<h2 className="text-xl font-medium">Browse by Your Framework</h2>
<div className="mt-4 flex flex-wrap gap-3">
{frameworksWithLibraries.map((framework) => {
const count = frameworkCounts[framework.value] ?? 0

return (
<Link
key={framework.value}
to="/libraries/$framework"
params={{
framework: framework.value,
}}
className="group inline-flex items-center gap-2 rounded-lg border border-gray-200 bg-white px-3 py-2 text-sm font-medium text-gray-800 shadow-sm transition-all hover:-translate-y-0.5 hover:border-current hover:shadow-md dark:border-gray-800 dark:bg-gray-900 dark:text-gray-100"
>
<img
src={framework.logo}
alt=""
loading="lazy"
className="h-5 w-5 object-contain"
/>
<span>{framework.label}</span>
<span className="text-gray-500 dark:text-gray-400">
{count} {count === 1 ? 'library' : 'libraries'}
</span>
</Link>
)
})}
</div>
</section>

<div
className={`grid grid-cols-1 gap-6 gap-y-8 justify-center mt-8
sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-3`}
Expand Down
Loading
Loading