[APP-2160] Render alf Context directly in StandardSiteThemeProvider

Nesting a full ThemeProvider spun up its own font-scale state, freezing
the SubscribeButton subtree from runtime parent updates. Reuse the
parent alf value and only swap the themes map.
This commit is contained in:
Eric Bailey
2026-05-22 15:11:17 -05:00
parent 827bb42d60
commit 8cc535513f
@@ -1,10 +1,12 @@
import {useMemo} from 'react'
import {type AppBskyEmbedExternal} from '@atproto/api' import {type AppBskyEmbedExternal} from '@atproto/api'
import {ThemeProvider, useAlf, utils} from '#/alf' import {Context, useAlf, utils} from '#/alf'
/** /**
* Overrides only the values needed for `secondary_inverted` buttons atm. * Overrides only the values needed for `secondary_inverted` buttons atm.
*
* Renders the alf Context directly (rather than nesting a ThemeProvider) so
* that font-scale and other parent state stay live in the subtree.
*/ */
export function StandardSiteThemeProvider({ export function StandardSiteThemeProvider({
view, view,
@@ -14,9 +16,8 @@ export function StandardSiteThemeProvider({
children: React.ReactNode children: React.ReactNode
}) { }) {
const alf = useAlf() const alf = useAlf()
const themesOverride = useMemo(() => {
const {accentRGB, accentForegroundRGB} = view.source?.theme || {} const {accentRGB, accentForegroundRGB} = view.source?.theme || {}
if (!accentRGB || !accentForegroundRGB) return alf.themes if (!accentRGB || !accentForegroundRGB) return children
const accent = utils.rgbToHex(accentRGB.r, accentRGB.g, accentRGB.b) const accent = utils.rgbToHex(accentRGB.r, accentRGB.g, accentRGB.b)
const accentForeground = utils.rgbToHex( const accentForeground = utils.rgbToHex(
@@ -24,67 +25,43 @@ export function StandardSiteThemeProvider({
accentForegroundRGB.g, accentForegroundRGB.g,
accentForegroundRGB.b, accentForegroundRGB.b,
) )
const atoms = { const atomsOverride = {
text_inverted: {color: accentForeground}, text_inverted: {color: accentForeground},
} }
const palette = { const paletteOverride = {
contrast_975: utils.darken(accent, 5), // hover contrast_975: utils.darken(accent, 5), // hover
contrast_900: accent, // bg contrast_900: accent, // bg
contrast_600: utils.lighten(accent, 5), // disabled bg contrast_600: utils.lighten(accent, 5), // disabled bg
contrast_300: accentForeground, // disabled text contrast_300: accentForeground, // disabled text
} }
return {
lightPalette: { const themes = {
...alf.themes.lightPalette, ...alf.themes,
...palette, lightPalette: {...alf.themes.lightPalette, ...paletteOverride},
}, darkPalette: {...alf.themes.darkPalette, ...paletteOverride},
darkPalette: { dimPalette: {...alf.themes.dimPalette, ...paletteOverride},
...alf.themes.darkPalette,
...palette,
},
dimPalette: {
...alf.themes.dimPalette,
...palette,
},
light: { light: {
...alf.themes.light, ...alf.themes.light,
atoms: { atoms: {...alf.themes.light.atoms, ...atomsOverride},
...alf.themes.light.atoms, palette: {...alf.themes.light.palette, ...paletteOverride},
...atoms,
},
palette: {
...alf.themes.light.palette,
...palette,
},
}, },
dark: { dark: {
...alf.themes.dark, ...alf.themes.dark,
atoms: { atoms: {...alf.themes.dark.atoms, ...atomsOverride},
...alf.themes.dark.atoms, palette: {...alf.themes.dark.palette, ...paletteOverride},
...atoms,
},
palette: {
...alf.themes.dark.palette,
...palette,
},
}, },
dim: { dim: {
...alf.themes.dim, ...alf.themes.dim,
atoms: { atoms: {...alf.themes.dim.atoms, ...atomsOverride},
...alf.themes.dim.atoms, palette: {...alf.themes.dim.palette, ...paletteOverride},
...atoms,
},
palette: {
...alf.themes.dim.palette,
...palette,
},
}, },
} }
}, [alf, view])
return ( const value = {
<ThemeProvider theme={alf.themeName} themesOverride={themesOverride}> ...alf,
{children} themes,
</ThemeProvider> theme: themes[alf.themeName],
) }
return <Context.Provider value={value}>{children}</Context.Provider>
} }