Skip to content

Commit 63e0751

Browse files
authored
Merge branch 'main' into fix/sidebar-close-on-dropdown
2 parents 04f00be + c937585 commit 63e0751

16 files changed

Lines changed: 74 additions & 23 deletions

src/components/Navbar.tsx

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,7 @@ import {
3030
} from 'lucide-react'
3131
import { ThemeToggle } from './ThemeToggle'
3232
import { SearchButton } from './SearchButton'
33-
import {
34-
libraries,
35-
findLibrary,
36-
SIDEBAR_LIBRARY_IDS,
37-
type LibrarySlim,
38-
} from '~/libraries'
33+
import { libraries, SIDEBAR_LIBRARY_IDS, type LibrarySlim } from '~/libraries'
3934
import { useClickOutside } from '~/hooks/useClickOutside'
4035
import { GithubIcon } from '~/components/icons/GithubIcon'
4136
import { DiscordIcon } from '~/components/icons/DiscordIcon'
@@ -139,14 +134,11 @@ const MobileCard = ({
139134
export function Navbar({ children }: { children: React.ReactNode }) {
140135
const matches = useMatches()
141136

142-
const { Title, library } = React.useMemo(() => {
137+
const { Title } = React.useMemo(() => {
143138
const match = [...matches].reverse().find((m) => m.staticData.Title)
144-
const params = match?.params as { libraryId?: string } | undefined
145-
const libraryId = params?.libraryId
146139

147140
return {
148141
Title: match?.staticData.Title ?? null,
149-
library: libraryId ? findLibrary(libraryId) : null,
150142
}
151143
}, [matches])
152144

@@ -227,8 +219,8 @@ export function Navbar({ children }: { children: React.ReactNode }) {
227219
const socialLinks = (
228220
<div className="flex items-center [&_a]:p-1.5 [&_a]:opacity-50 [&_a:hover]:opacity-100 [&_a]:transition-opacity [&_svg]:text-sm">
229221
<a
230-
href={`https://github.com/${library?.repo ?? 'tanstack'}`}
231-
aria-label={`Follow ${library?.name ?? 'TanStack'} on GitHub`}
222+
href="https://github.com/TanStack"
223+
aria-label="Follow TanStack on GitHub"
232224
>
233225
<GithubIcon />
234226
</a>
@@ -621,7 +613,7 @@ export function Navbar({ children }: { children: React.ReactNode }) {
621613
{
622614
label: 'GitHub',
623615
icon: GithubIcon,
624-
to: 'https://github.com/tanstack',
616+
to: 'https://github.com/TanStack',
625617
},
626618
{
627619
label: 'Ethos',

src/components/ThemeToggle.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,17 @@ export function ThemeToggle() {
1515
const label =
1616
themeMode === 'auto' ? 'Auto' : themeMode === 'light' ? 'Light' : 'Dark'
1717

18+
const nextLabel =
19+
themeMode === 'auto' ? 'light' : themeMode === 'light' ? 'dark' : 'auto'
20+
1821
return (
19-
<Button variant="ghost" size="xs" onClick={handleToggleMode}>
22+
<Button
23+
variant="ghost"
24+
size="xs"
25+
onClick={handleToggleMode}
26+
aria-label={`Theme: ${label}. Switch to ${nextLabel} mode.`}
27+
title={`Theme: ${label}. Switch to ${nextLabel} mode.`}
28+
>
2029
{themeMode === 'auto' ? (
2130
<SunMoon className="w-3.5 h-3.5" />
2231
) : (

src/router.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ declare module '@tanstack/react-router' {
7878
baseParent?: boolean
7979
Title?: () => any
8080
showNavbar?: boolean
81+
includeSearchInCanonical?: boolean
8182
}
8283
}
8384

src/routes/$libraryId/$version.docs.npm-stats.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ export const Route = createFileRoute('/$libraryId/$version/docs/npm-stats')({
8383
height: v.fallback(v.optional(v.number(), 400), 400),
8484
}),
8585
component: RouteComponent,
86+
staticData: {
87+
includeSearchInCanonical: true,
88+
},
8689
})
8790

8891
type NpmStatsSearch = {

src/routes/__root.tsx

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,21 @@ function ShellComponent({ children }: { children: React.ReactNode }) {
184184
select: (s) => s.location?.pathname || '/',
185185
})
186186

187+
const canonicalSearchStr = useRouterState({
188+
select: (s) => s.location?.searchStr || '',
189+
})
190+
191+
const includeSearchInCanonical = useMatches({
192+
select: (s) =>
193+
s.some((d) => d.staticData?.includeSearchInCanonical === true),
194+
})
195+
187196
const preferredCanonicalPath = getCanonicalPath(canonicalPath)
188-
const pageUrl = canonicalUrl(preferredCanonicalPath ?? canonicalPath)
197+
const canonicalSearch = includeSearchInCanonical ? canonicalSearchStr : ''
198+
const pageUrl = canonicalUrl(
199+
preferredCanonicalPath ?? canonicalPath,
200+
canonicalSearch,
201+
)
189202

190203
const showDevtools = import.meta.env.DEV && canShowDevtools
191204

@@ -199,7 +212,10 @@ function ShellComponent({ children }: { children: React.ReactNode }) {
199212
<html lang="en" className={htmlClass} suppressHydrationWarning>
200213
<head>
201214
{preferredCanonicalPath ? (
202-
<link rel="canonical" href={canonicalUrl(preferredCanonicalPath)} />
215+
<link
216+
rel="canonical"
217+
href={canonicalUrl(preferredCanonicalPath, canonicalSearch)}
218+
/>
203219
) : null}
204220
<meta property="og:url" content={pageUrl} />
205221
<meta name="twitter:url" content={pageUrl} />
@@ -259,18 +275,23 @@ function SearchHotkeyController() {
259275

260276
React.useEffect(() => {
261277
const handleGlobalKeyDown = (event: KeyboardEvent) => {
262-
if (event.defaultPrevented) return
263278
if (!(event.metaKey || event.ctrlKey)) return
264-
if (event.key.toLowerCase() !== 'k') return
279+
if (event.altKey || event.shiftKey) return
280+
// Match both `key` and `code` so the shortcut works on non-QWERTY layouts.
281+
const isK = event.key.toLowerCase() === 'k' || event.code === 'KeyK'
282+
if (!isK) return
265283

266284
event.preventDefault()
285+
event.stopPropagation()
267286
setHasOpenedSearch(true)
268287
openSearch()
269288
}
270289

271-
window.addEventListener('keydown', handleGlobalKeyDown)
290+
document.addEventListener('keydown', handleGlobalKeyDown, { capture: true })
272291
return () => {
273-
window.removeEventListener('keydown', handleGlobalKeyDown)
292+
document.removeEventListener('keydown', handleGlobalKeyDown, {
293+
capture: true,
294+
})
274295
}
275296
}, [openSearch])
276297

src/routes/builder.index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export const Route = createFileRoute('/builder/')({
3131
validateSearch: builderSearchSchema,
3232
component: RouteComponent,
3333
staticData: {
34+
includeSearchInCanonical: true,
3435
Title: () => (
3536
<Link
3637
to="/builder"

src/routes/intent/registry/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ export const Route = createFileRoute('/intent/registry/')({
5858
}),
5959
}),
6060
component: IntentRegistryPage,
61+
staticData: {
62+
includeSearchInCanonical: true,
63+
},
6164
})
6265

6366
function IntentRegistryPage() {

src/routes/maintainers.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ const searchSchema = v.object({
3535
export const Route = createFileRoute('/maintainers')({
3636
component: RouteComponent,
3737
validateSearch: searchSchema,
38+
staticData: {
39+
includeSearchInCanonical: true,
40+
},
3841
head: () => ({
3942
meta: seo({
4043
title: 'Maintainers | TanStack',

src/routes/partners.index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ function getPartnerFilterAnalytics(search: PartnersSearch) {
7878
export const Route = createFileRoute('/partners/')({
7979
component: PartnersIndexPage,
8080
validateSearch: searchSchema,
81+
staticData: {
82+
includeSearchInCanonical: true,
83+
},
8184
head: () => ({
8285
meta: seo({
8386
title: 'Partners',

src/routes/shop.collections.$handle.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ export const Route = createFileRoute('/shop/collections/$handle')({
6363
}
6464
},
6565
component: CollectionPage,
66+
staticData: {
67+
includeSearchInCanonical: true,
68+
},
6669
})
6770

6871
function CollectionPage() {

0 commit comments

Comments
 (0)