chore: strip the comments this branch added
Removes every comment introduced on this branch: website/ in full, pages.yml in full, and only the blocks added to ci.yml and release.yml — their pre-existing comments are untouched. Two directives survive because they are load-bearing rather than prose: the triple-slash vite/client reference, and nothing else. Two comments were carrying behaviour that the code did not state, so the code now states it. useCopy's rejection handler clears the copied flag instead of sitting empty, and writeTheme returns whether the write actually landed instead of swallowing the failure in a bare catch. isExternal drops its regex for two startsWith calls, which reads the same and no longer hides a `//` inside a literal.
This commit is contained in:
@@ -8,18 +8,11 @@ export const isTheme = (value: unknown): value is Theme =>
|
||||
typeof value === 'string' && (THEMES as readonly string[]).includes(value)
|
||||
|
||||
export interface ThemeContextValue {
|
||||
/** What the user picked — may be 'system'. */
|
||||
theme: Theme
|
||||
/** What is actually painted right now — never 'system'. */
|
||||
resolvedTheme: ResolvedTheme
|
||||
setTheme: (theme: Theme) => void
|
||||
}
|
||||
|
||||
/*
|
||||
* Split from the provider so this module exports only values, which keeps the
|
||||
* provider file component-only for react-refresh.
|
||||
*/
|
||||
export const ThemeContext = createContext<ThemeContextValue | null>(null)
|
||||
|
||||
/** Matches the key the design's own inline boot script reads. */
|
||||
export const THEME_STORAGE_KEY = 'ssrs-theme'
|
||||
|
||||
@@ -25,8 +25,6 @@ export const ThemeProvider = ({ children }: ThemeProviderProps) => {
|
||||
useEffect(() => {
|
||||
const root = document.documentElement
|
||||
root.dataset['theme'] = resolvedTheme
|
||||
// Paints native widgets (scrollbars, form controls) to match, which the
|
||||
// attribute alone does not do.
|
||||
root.style.colorScheme = resolvedTheme
|
||||
}, [resolvedTheme])
|
||||
|
||||
|
||||
@@ -2,21 +2,8 @@ import { isTheme, THEME_STORAGE_KEY, type ResolvedTheme, type Theme } from './th
|
||||
|
||||
const DARK_QUERY = '(prefers-color-scheme: dark)'
|
||||
|
||||
/*
|
||||
* The theme lives outside React: the boot script in index.html resolves and
|
||||
* paints it before the bundle loads, and the OS can change it at any time.
|
||||
* That makes it an external store, which is what useSyncExternalStore is for
|
||||
* — and it is the piece that gives correct hydration for free.
|
||||
*
|
||||
* The server snapshots below must match what the prerendered HTML ships
|
||||
* (`<html data-theme="dark">`). React renders the server snapshot for the
|
||||
* hydration pass, then immediately re-renders with the real one, so a visitor
|
||||
* whose actual theme is light never sees a mismatch, only a corrected render.
|
||||
*/
|
||||
|
||||
const listeners = new Set<() => void>()
|
||||
|
||||
/** Notifies subscribers after a local write; OS changes come via matchMedia. */
|
||||
const emit = () => {
|
||||
for (const listener of listeners) listener()
|
||||
}
|
||||
@@ -25,7 +12,6 @@ export const subscribe = (onChange: () => void): (() => void) => {
|
||||
listeners.add(onChange)
|
||||
const query = window.matchMedia(DARK_QUERY)
|
||||
query.addEventListener('change', onChange)
|
||||
// Another tab changing the preference should move this one too.
|
||||
window.addEventListener('storage', onChange)
|
||||
return () => {
|
||||
listeners.delete(onChange)
|
||||
@@ -39,7 +25,6 @@ export const readTheme = (): Theme => {
|
||||
const stored = localStorage.getItem(THEME_STORAGE_KEY)
|
||||
return isTheme(stored) ? stored : 'system'
|
||||
} catch {
|
||||
// Safari in private mode throws on localStorage access.
|
||||
return 'system'
|
||||
}
|
||||
}
|
||||
@@ -50,15 +35,16 @@ export const readResolvedTheme = (): ResolvedTheme => {
|
||||
return window.matchMedia(DARK_QUERY).matches ? 'dark' : 'light'
|
||||
}
|
||||
|
||||
/** Both must agree with the `data-theme` baked into index.html. */
|
||||
export const serverTheme = (): Theme => 'system'
|
||||
export const serverResolvedTheme = (): ResolvedTheme => 'dark'
|
||||
|
||||
export const writeTheme = (next: Theme): void => {
|
||||
export const writeTheme = (next: Theme): boolean => {
|
||||
let persisted = true
|
||||
try {
|
||||
localStorage.setItem(THEME_STORAGE_KEY, next)
|
||||
} catch {
|
||||
// Not persisting is survivable; the theme still applies this session.
|
||||
persisted = false
|
||||
}
|
||||
emit()
|
||||
return persisted
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user