DP17: use folds Icons + named brand-color consts in UrlPreviewCard
Replace literal-glyph UI icons in the URL preview cards with folds Icon/Icons components, and hoist hardcoded provider brand hex values into a single named BRAND_COLORS map. Glyph -> folds icon: - TikTok/Spotify musical note (♫) -> Icons.VolumeHigh - Portrait play button (▶) -> Icons.Play - Reddit comment count (💬) -> Icons.Message - Steam gear (⚙) -> Icons.Setting All use size="Inherit" so they keep the surrounding font-size/color. Brand hex now referenced via BRAND_COLORS (tiktok, spotify, steam, twitch, reddit, discord, npm, stackOverflow) instead of scattered literals; colors are byte-for-byte identical and remain fixed brand identities (not converted to TDS theme vars). The game controller glyph (🎮) is left as-is: folds has no game/ controller icon and no close semantic match. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,22 @@ import {
|
|||||||
|
|
||||||
const linkStyles = { color: color.Success.Main };
|
const linkStyles = { color: color.Success.Main };
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Provider brand identity colors.
|
||||||
|
// These are official brand-palette values (logos, badges), NOT theme colors,
|
||||||
|
// so they intentionally stay as fixed hex and must not become --lt-* TDS vars.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
const BRAND_COLORS = {
|
||||||
|
tiktok: '#EE1D52',
|
||||||
|
spotify: '#1db954',
|
||||||
|
steam: '#c7d5e0',
|
||||||
|
twitch: '#9146ff',
|
||||||
|
reddit: '#ff4500',
|
||||||
|
discord: '#5865f2',
|
||||||
|
npm: '#cb3837',
|
||||||
|
stackOverflow: '#f48024',
|
||||||
|
} as const;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Helpers — URL parsing & variant detection
|
// Helpers — URL parsing & variant detection
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -474,7 +490,11 @@ function TikTokCard({
|
|||||||
<div className={previewCss.ShortsHeader}>
|
<div className={previewCss.ShortsHeader}>
|
||||||
{/* TikTok badge with musical note icon */}
|
{/* TikTok badge with musical note icon */}
|
||||||
<span className={`${previewCss.SiteBadge} ${previewCss.BadgeTikTok}`}>
|
<span className={`${previewCss.SiteBadge} ${previewCss.BadgeTikTok}`}>
|
||||||
<span style={{ color: '#EE1D52', marginRight: '2px' }}>♫</span>
|
<Icon
|
||||||
|
style={{ color: BRAND_COLORS.tiktok, marginRight: '2px' }}
|
||||||
|
size="Inherit"
|
||||||
|
src={Icons.VolumeHigh}
|
||||||
|
/>
|
||||||
TikTok
|
TikTok
|
||||||
</span>
|
</span>
|
||||||
{username && (
|
{username && (
|
||||||
@@ -512,12 +532,14 @@ function TikTokCard({
|
|||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
<div className={previewCss.PortraitPlayOverlay}>
|
<div className={previewCss.PortraitPlayOverlay}>
|
||||||
<div className={previewCss.PortraitPlayButton}>▶</div>
|
<div className={previewCss.PortraitPlayButton}>
|
||||||
|
<Icon size="Inherit" src={Icons.Play} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
) : (
|
) : (
|
||||||
<div className={previewCss.PortraitPlaceholder}>
|
<div className={previewCss.PortraitPlaceholder}>
|
||||||
<span style={{ color: '#EE1D52' }}>♫</span>
|
<Icon style={{ color: BRAND_COLORS.tiktok }} size="Inherit" src={Icons.VolumeHigh} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<Box grow="Yes" direction="Column" gap="100">
|
<Box grow="Yes" direction="Column" gap="100">
|
||||||
@@ -828,7 +850,7 @@ function TwitchCard({
|
|||||||
width={28}
|
width={28}
|
||||||
height={28}
|
height={28}
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="#9146ff"
|
fill={BRAND_COLORS.twitch}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
role="img"
|
role="img"
|
||||||
>
|
>
|
||||||
@@ -921,11 +943,11 @@ function RedditCard({
|
|||||||
width={28}
|
width={28}
|
||||||
height={28}
|
height={28}
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="#ff4500"
|
fill={BRAND_COLORS.reddit}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
role="img"
|
role="img"
|
||||||
>
|
>
|
||||||
<circle cx="12" cy="12" r="12" fill="#ff4500" />
|
<circle cx="12" cy="12" r="12" fill={BRAND_COLORS.reddit} />
|
||||||
<path
|
<path
|
||||||
fill="#ffffff"
|
fill="#ffffff"
|
||||||
d="M20 12a2 2 0 0 0-2-2 2 2 0 0 0-1.36.54C15.28 9.8 13.72 9.4 12 9.39l.7-3.26 2.23.47a1.4 1.4 0 1 0 .15-.69l-2.5-.52a.25.25 0 0 0-.29.19l-.78 3.65c-1.74.06-3.3.46-4.63 1.17A2 2 0 0 0 4 12a2 2 0 0 0 1.07 1.76 3.5 3.5 0 0 0 0 .49C5.07 16.69 8.27 19 12.07 19s6.97-2.31 6.97-4.75a3.5 3.5 0 0 0 0-.47A2 2 0 0 0 20 12zm-13 2a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm5.59 2.71c-.72.72-2.1.77-2.53.77s-1.82-.05-2.53-.77a.25.25 0 0 1 .35-.35c.46.46 1.48.62 2.18.62s1.72-.16 2.18-.62a.25.25 0 0 1 .35.35zm-.15-1.71a1 1 0 1 1 2 0 1 1 0 0 1-2 0z"
|
d="M20 12a2 2 0 0 0-2-2 2 2 0 0 0-1.36.54C15.28 9.8 13.72 9.4 12 9.39l.7-3.26 2.23.47a1.4 1.4 0 1 0 .15-.69l-2.5-.52a.25.25 0 0 0-.29.19l-.78 3.65c-1.74.06-3.3.46-4.63 1.17A2 2 0 0 0 4 12a2 2 0 0 0 1.07 1.76 3.5 3.5 0 0 0 0 .49C5.07 16.69 8.27 19 12.07 19s6.97-2.31 6.97-4.75a3.5 3.5 0 0 0 0-.47A2 2 0 0 0 20 12zm-13 2a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm5.59 2.71c-.72.72-2.1.77-2.53.77s-1.82-.05-2.53-.77a.25.25 0 0 1 .35-.35c.46.46 1.48.62 2.18.62s1.72-.16 2.18-.62a.25.25 0 0 1 .35.35zm-.15-1.71a1 1 0 1 1 2 0 1 1 0 0 1-2 0z"
|
||||||
@@ -1005,7 +1027,11 @@ function RedditCard({
|
|||||||
{/* Stats row */}
|
{/* Stats row */}
|
||||||
<div className={previewCss.RedditMeta}>
|
<div className={previewCss.RedditMeta}>
|
||||||
{upvotes && <span className={previewCss.RedditUpvote}>▲ {upvotes}</span>}
|
{upvotes && <span className={previewCss.RedditUpvote}>▲ {upvotes}</span>}
|
||||||
{comments && <span>💬 {comments}</span>}
|
{comments && (
|
||||||
|
<span>
|
||||||
|
<Icon size="Inherit" src={Icons.Message} /> {comments}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
@@ -1473,7 +1499,11 @@ function SpotifyCard({ url, prev }: { url: string; prev: IPreviewUrlResponse })
|
|||||||
justifyContent="Center"
|
justifyContent="Center"
|
||||||
className={previewCss.IconWrapper}
|
className={previewCss.IconWrapper}
|
||||||
>
|
>
|
||||||
<span style={{ fontSize: '2rem', color: '#1db954' }}>♫</span>
|
<Icon
|
||||||
|
style={{ fontSize: '2rem', color: BRAND_COLORS.spotify }}
|
||||||
|
size="Inherit"
|
||||||
|
src={Icons.VolumeHigh}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
<UrlPreviewContent>
|
<UrlPreviewContent>
|
||||||
@@ -1533,7 +1563,11 @@ function SteamCard({ url, prev }: { url: string; prev: IPreviewUrlResponse }) {
|
|||||||
justifyContent="Center"
|
justifyContent="Center"
|
||||||
className={previewCss.IconWrapper}
|
className={previewCss.IconWrapper}
|
||||||
>
|
>
|
||||||
<span style={{ fontSize: '1.5rem', color: '#c7d5e0' }}>⚙</span>
|
<Icon
|
||||||
|
style={{ fontSize: '1.5rem', color: BRAND_COLORS.steam }}
|
||||||
|
size="Inherit"
|
||||||
|
src={Icons.Setting}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
<UrlPreviewContent>
|
<UrlPreviewContent>
|
||||||
@@ -1640,7 +1674,7 @@ function DiscordCard({ url, prev }: { url: string; prev: IPreviewUrlResponse })
|
|||||||
width={28}
|
width={28}
|
||||||
height={28}
|
height={28}
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="#5865f2"
|
fill={BRAND_COLORS.discord}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
role="img"
|
role="img"
|
||||||
>
|
>
|
||||||
@@ -1693,13 +1727,13 @@ function NpmCard({ url, prev }: { url: string; prev: IPreviewUrlResponse }) {
|
|||||||
>
|
>
|
||||||
{/* npm logo — simple square mark */}
|
{/* npm logo — simple square mark */}
|
||||||
<svg width={32} height={32} viewBox="0 0 18 7" fill="none" aria-hidden="true" role="img">
|
<svg width={32} height={32} viewBox="0 0 18 7" fill="none" aria-hidden="true" role="img">
|
||||||
<rect width="18" height="7" fill="#cb3837" />
|
<rect width="18" height="7" fill={BRAND_COLORS.npm} />
|
||||||
<rect x="1" y="1" width="4" height="5" fill="white" />
|
<rect x="1" y="1" width="4" height="5" fill="white" />
|
||||||
<rect x="2" y="1" width="1" height="4" fill="#cb3837" />
|
<rect x="2" y="1" width="1" height="4" fill={BRAND_COLORS.npm} />
|
||||||
<rect x="6" y="1" width="4" height="5" fill="white" />
|
<rect x="6" y="1" width="4" height="5" fill="white" />
|
||||||
<rect x="7" y="1" width="1" height="3" fill="#cb3837" />
|
<rect x="7" y="1" width="1" height="3" fill={BRAND_COLORS.npm} />
|
||||||
<rect x="11" y="1" width="4" height="4" fill="white" />
|
<rect x="11" y="1" width="4" height="4" fill="white" />
|
||||||
<rect x="12" y="1" width="1" height="3" fill="#cb3837" />
|
<rect x="12" y="1" width="1" height="3" fill={BRAND_COLORS.npm} />
|
||||||
</svg>
|
</svg>
|
||||||
</Box>
|
</Box>
|
||||||
<UrlPreviewContent>
|
<UrlPreviewContent>
|
||||||
@@ -1747,7 +1781,7 @@ function StackOverflowCard({ url, prev }: { url: string; prev: IPreviewUrlRespon
|
|||||||
width={28}
|
width={28}
|
||||||
height={28}
|
height={28}
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="#f48024"
|
fill={BRAND_COLORS.stackOverflow}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
role="img"
|
role="img"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user