From b514362868c68870aa3e82df2fe496677a06c1fb Mon Sep 17 00:00:00 2001 From: muzzlol Date: Tue, 4 Nov 2025 01:55:52 +0530 Subject: [PATCH] feat: prevent overscroll bounce on all browsers and sync mobile status bar with theme - Add overscroll-behavior: none to prevent bounce effect across all browsers - Implement dynamic theme-color meta tag that syncs with site theme toggle - Add THEME_COLORS constant to utils for consistent color references - Update ThemeProvider to set status bar color on theme change --- src/components/ThemeProvider.tsx | 9 +++++++++ src/libraries/maintainers.ts | 2 +- src/routes/__root.tsx | 11 +++++++++++ src/styles/app.css | 1 + src/utils/utils.ts | 7 +++++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/components/ThemeProvider.tsx b/src/components/ThemeProvider.tsx index 093c5198..93bb3b33 100644 --- a/src/components/ThemeProvider.tsx +++ b/src/components/ThemeProvider.tsx @@ -3,6 +3,7 @@ import { createClientOnlyFn, createIsomorphicFn } from '@tanstack/react-start' import * as React from 'react' import { createContext, ReactNode, useEffect, useState } from 'react' import { z } from 'zod' +import { THEME_COLORS } from '~/utils/utils' const themeModeSchema = z.enum(['light', 'dark', 'auto']) const resolvedThemeSchema = z.enum(['light', 'dark']) @@ -46,6 +47,14 @@ const updateThemeClass = createClientOnlyFn((themeMode: ThemeMode) => { if (themeMode === 'auto') { root.classList.add('auto') } + + const metaThemeColor = document.querySelector('meta[name="theme-color"]') + if (metaThemeColor) { + metaThemeColor.setAttribute( + 'content', + newTheme === 'dark' ? THEME_COLORS.dark : THEME_COLORS.light + ) + } }) const setupPreferredListener = createClientOnlyFn(() => { diff --git a/src/libraries/maintainers.ts b/src/libraries/maintainers.ts index 9c3a77cc..bbc03766 100644 --- a/src/libraries/maintainers.ts +++ b/src/libraries/maintainers.ts @@ -424,7 +424,7 @@ export const allMaintainers: Maintainer[] = [ social: { twitter: 'https://x.com/beaussan', bluesky: 'https://bsky.app/profile/beaussan.io', - website: 'https://beaussan.io/' + website: 'https://beaussan.io/', }, }, ] diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index f7c2f647..533e5df8 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -33,6 +33,7 @@ import { authClient } from '../utils/auth.client' import { LibrariesLayout } from './_libraries/route' import { TanStackUser } from 'convex/auth' +import { THEME_COLORS } from '~/utils/utils' export const Route = createRootRouteWithContext<{ queryClient: QueryClient @@ -49,6 +50,16 @@ export const Route = createRootRouteWithContext<{ name: 'viewport', content: 'width=device-width, initial-scale=1', }, + { + name: 'theme-color', + content: THEME_COLORS.light, + media: '(prefers-color-scheme: light)', + }, + { + name: 'theme-color', + content: THEME_COLORS.dark, + media: '(prefers-color-scheme: dark)', + }, ...seo({ title: 'TanStack | High Quality Open-Source Software for Web Developers', diff --git a/src/styles/app.css b/src/styles/app.css index 5a0009c8..b4f579c8 100644 --- a/src/styles/app.css +++ b/src/styles/app.css @@ -68,6 +68,7 @@ button { html, body { @apply text-gray-900 bg-gray-50 dark:bg-gray-900 dark:text-gray-200; + overscroll-behavior: none; } .using-mouse * { diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 525866fe..14570a7d 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -175,3 +175,10 @@ export async function logTime( console.log(`${lable}: ${(end - start).toLocaleString()} ms`) return result as any } + +export const THEME_COLORS = { + light: '#f9fafb', // Tailwind gray-50 + dark: '#101828', // Tailwind gray-900 +} as const + +export type ThemeColor = keyof typeof THEME_COLORS