Gate StandardSite subscribe button custom theme on AAA contrast (#10735)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -427,6 +427,26 @@ export function SubscribeButton({
|
||||
? l`Subscribe on ${highlightedPublisher.name}`
|
||||
: l`View publication`
|
||||
|
||||
/*
|
||||
* The custom site theme paints the button background with `accent` and the
|
||||
* text with `accentForeground`. Only honor it when that pairing clears WCAG
|
||||
* AAA (4.5:1) for large text, which the button's bold label qualifies as.
|
||||
* Otherwise we fall through to the default `secondary_inverted` styling,
|
||||
* which is guaranteed to be legible.
|
||||
*/
|
||||
const {accentRGB, accentForegroundRGB} = view.source?.theme || {}
|
||||
let useCustomTheme = false
|
||||
if (accentRGB && accentForegroundRGB) {
|
||||
const accent = utils.rgbToHex(accentRGB.r, accentRGB.g, accentRGB.b)
|
||||
const accentForeground = utils.rgbToHex(
|
||||
accentForegroundRGB.r,
|
||||
accentForegroundRGB.g,
|
||||
accentForegroundRGB.b,
|
||||
)
|
||||
const ratio = utils.contrastRatio(accent, accentForeground)
|
||||
useCustomTheme = ratio !== null && ratio >= 4.5
|
||||
}
|
||||
|
||||
if (!view.source) return null
|
||||
|
||||
const publicationTitle = view.source.title
|
||||
@@ -468,36 +488,42 @@ export function SubscribeButton({
|
||||
}
|
||||
}
|
||||
|
||||
const button = (
|
||||
<Link
|
||||
shouldProxy
|
||||
to={view.source.uri}
|
||||
label={label}
|
||||
size="small"
|
||||
color="secondary_inverted"
|
||||
style={[
|
||||
style,
|
||||
a.gap_sm,
|
||||
preview ? a.pointer_events_none : a.pointer_events_auto,
|
||||
]}
|
||||
onPress={onPress}
|
||||
onLongPress={onLongPress}>
|
||||
{highlightedPublisher ? (
|
||||
<>
|
||||
<View style={[a.flex_row, a.align_center, {gap: 7}]}>
|
||||
<ButtonIcon icon={highlightedPublisher.Icon} size="md" />
|
||||
</View>
|
||||
<ButtonText>{cta}</ButtonText>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<ButtonText>{cta}</ButtonText>
|
||||
<ButtonIcon icon={ArrowTopRightIcon} />
|
||||
</>
|
||||
)}
|
||||
</Link>
|
||||
)
|
||||
|
||||
if (!useCustomTheme) {
|
||||
return button
|
||||
}
|
||||
|
||||
return (
|
||||
<StandardSiteThemeProvider view={view}>
|
||||
<Link
|
||||
shouldProxy
|
||||
to={view.source.uri}
|
||||
label={label}
|
||||
size="small"
|
||||
color="secondary_inverted"
|
||||
style={[
|
||||
style,
|
||||
a.gap_sm,
|
||||
preview ? a.pointer_events_none : a.pointer_events_auto,
|
||||
]}
|
||||
onPress={onPress}
|
||||
onLongPress={onLongPress}>
|
||||
{highlightedPublisher ? (
|
||||
<>
|
||||
<View style={[a.flex_row, a.align_center, {gap: 7}]}>
|
||||
<ButtonIcon icon={highlightedPublisher.Icon} size="md" />
|
||||
</View>
|
||||
<ButtonText>{cta}</ButtonText>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<ButtonText>{cta}</ButtonText>
|
||||
<ButtonIcon icon={ArrowTopRightIcon} />
|
||||
</>
|
||||
)}
|
||||
</Link>
|
||||
</StandardSiteThemeProvider>
|
||||
<StandardSiteThemeProvider view={view}>{button}</StandardSiteThemeProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user