From f3d20e593fdb02163dc42f5b80a0b0ed13f61282 Mon Sep 17 00:00:00 2001 From: "xuan.huang" <5563315+Huxpro@users.noreply.github.com> Date: Wed, 3 Jun 2026 09:31:48 -0700 Subject: [PATCH 1/5] refactor: unify platform icons across homepage, APIStatus, and PlatformSvg Platform icons used to live in three places with three different rendering strategies: SVGR `?react` imports with `fill` overrides on the homepage, inline JSX SVGs with `currentColor` in api-status, and mask-image with currentColor in PlatformIcon. APITable already used mask-image from the compat-table icon set. Consolidate around the compat-table set as the canonical icon source and route every consumer through ``: - `PlatformIcon.tsx`: drop the `@assets/home/*` imports, route through one `ICON_NAME_TO_URL` table backed by `compat-table/assets/icons/`. The mapping reuses compat-table's `mapPlatformNameToIconName` so the homepage and APITable stay in lockstep when new platforms are added. - `home-comps/features/icon.tsx`: replace per-platform SVGR imports with thin `` wrappers and a shared `.platform-icon` size class. - `api-status/constants.tsx`: replace inline JSX SVGs and the `createMaskIcon` helper with a single `makeIcon(platformName)` factory that delegates to ``. Visible change: the homepage Android icon switches from the half-dome face to the full Bugdroid body that APITable / APISummary already used, so the two surfaces match. Change-Id: I63a57690e19a7bedee6a6a8c0838a873668b73bd --- src/components/api-status/constants.tsx | 79 ++---------- src/components/home-comps/features/icon.tsx | 38 ++---- .../home-comps/features/index.module.less | 38 +----- .../platform-navigation/PlatformIcon.tsx | 113 +++++++++--------- 4 files changed, 80 insertions(+), 188 deletions(-) diff --git a/src/components/api-status/constants.tsx b/src/components/api-status/constants.tsx index 2fa43d404..77ca2b96a 100644 --- a/src/components/api-status/constants.tsx +++ b/src/components/api-status/constants.tsx @@ -1,8 +1,6 @@ import React from 'react'; -import type { PlatformName } from '@lynx-js/lynx-compat-data'; import { cn } from '@/lib/utils'; -import MacOSIconAsset from '../api-table/compat-table/assets/icons/macos-text.svg'; -import WindowsIconAsset from '../api-table/compat-table/assets/icons/windows.svg'; +import { PlatformSvg } from '@/components/platform-navigation/PlatformIcon'; export interface PlatformConfig { label: string; @@ -16,75 +14,22 @@ export interface PlatformConfig { }; } -const AndroidIcon: React.FC<{ className?: string }> = ({ className }) => ( - - - -); - -const IOSIcon: React.FC<{ className?: string }> = ({ className }) => ( - - - -); - -const HarmonyIcon: React.FC<{ className?: string }> = ({ className }) => ( - - - -); - -const createMaskIcon = (svgUrl: string): React.FC<{ className?: string }> => { - const MaskIcon: React.FC<{ className?: string }> = ({ className }) => ( -
=> { + return ({ className }) => ( + ); - - return MaskIcon; }; -const MacOSIcon = createMaskIcon(MacOSIconAsset); -const WindowsIcon = createMaskIcon(WindowsIconAsset); - -const WebIcon: React.FC<{ className?: string }> = ({ className }) => ( - - - - - - - -); - -const ClayIcon: React.FC<{ className?: string }> = ({ className }) => ( - - - - - - - - - - - -); +const AndroidIcon = makeIcon('android'); +const IOSIcon = makeIcon('ios'); +const HarmonyIcon = makeIcon('harmony'); +const WebIcon = makeIcon('web_lynx'); +const ClayIcon = makeIcon('clay'); +const MacOSIcon = makeIcon('clay_macos'); +const WindowsIcon = makeIcon('clay_windows'); export const PLATFORM_CONFIG: Record = { android: { diff --git a/src/components/home-comps/features/icon.tsx b/src/components/home-comps/features/icon.tsx index fdb663f69..3e196d1dc 100644 --- a/src/components/home-comps/features/icon.tsx +++ b/src/components/home-comps/features/icon.tsx @@ -1,38 +1,20 @@ import React from 'react'; import { withBase } from '@rspress/core/runtime'; -import AndroidIcon from '@assets/home/home-icon-android.svg?react'; -import WebIcon from '@/components/api-table/compat-table/assets/icons/web.svg?react'; -import AppleIcon from '@assets/home/home-icon-apple.svg?react'; -import HarmonyIcon from '@assets/home/harmony.svg?react'; -import MacOSIcon from '@/components/api-table/compat-table/assets/icons/macos-text.svg?react'; -import WindowsIcon from '@assets/home/windows.svg?react'; +import { PlatformSvg } from '@/components/platform-navigation/PlatformIcon'; import ReactLynxIcon from '@/components/api-table/compat-table/assets/icons/reactlynx.svg?react'; import VueLynxIcon from '@assets/home/vue-lynx-logo.svg?react'; import styles from './index.module.less'; -const IconAndroid = () => { - return ; -}; - -const IconIOS = () => { - return ; -}; - -const IconWeb = () => { - return ; -}; +const PlatformIconWrapper = ({ platform }: { platform: string }) => ( + +); -const IconHarmony = () => { - return ; -}; - -const IconMacOS = () => { - return ; -}; - -const IconWindows = () => { - return ; -}; +const IconIOS = () => ; +const IconAndroid = () => ; +const IconWeb = () => ; +const IconHarmony = () => ; +const IconMacOS = () => ; +const IconWindows = () => ; const IconReactLynx = () => { return ; diff --git a/src/components/home-comps/features/index.module.less b/src/components/home-comps/features/index.module.less index ba9631d42..aea5e6cc2 100644 --- a/src/components/home-comps/features/index.module.less +++ b/src/components/home-comps/features/index.module.less @@ -35,41 +35,9 @@ box-sizing: border-box; display: flex; flex-direction: column; - .ios-icon { - path { - fill: var(--home-blog-btn-color) !important; - } - } - - .web-icon { - width: 18px; - height: 18px; - path { - fill: var(--home-blog-btn-color) !important; - } - } - - .harmony-icon { - width: 21px; - path { - fill: var(--home-blog-btn-color) !important; - } - } - - .macos-icon { - width: 18px; - height: 18px; - path { - fill: var(--home-blog-btn-color) !important; - } - } - - .windows-icon { - width: 18px; - height: 18px; - path { - fill: var(--home-blog-btn-color) !important; - } + .platform-icon { + --icon-size: 18px; + color: var(--home-blog-btn-color); } .reactlynx-icon { diff --git a/src/components/platform-navigation/PlatformIcon.tsx b/src/components/platform-navigation/PlatformIcon.tsx index 53d2ea9f3..2ee4bf6c5 100644 --- a/src/components/platform-navigation/PlatformIcon.tsx +++ b/src/components/platform-navigation/PlatformIcon.tsx @@ -3,31 +3,46 @@ import { cn } from '../../lib/utils'; import { mapPlatformNameToIconName } from '../api-table/compat-table/headers'; import { PlatformIconProps } from './types'; import './icon.scss'; -import AndroidIcon from '@assets/home/home-icon-android.svg'; -import WindowsIcon from '@assets/home/windows.svg'; -import IosIcon from '@assets/home/home-icon-apple.svg'; -import HarmonyIcon from '@assets/home/harmony.svg'; -import ClayIcon from '@assets/home/clay.svg'; -// Use the same HTML5 web icon and macOS text mark as the homepage features -// section so platform indicators stay consistent across the site. + +// Single canonical icon source for every platform-icon surface on the site. +// Adding a new platform = add an SVG here, extend ICON_NAME_TO_URL, done. +import AppleIcon from '@/components/api-table/compat-table/assets/icons/apple.svg'; +import AndroidIcon from '@/components/api-table/compat-table/assets/icons/android.svg'; +import HarmonyIcon from '@/components/api-table/compat-table/assets/icons/harmony.svg'; import WebIcon from '@/components/api-table/compat-table/assets/icons/web.svg'; +import WindowsIcon from '@/components/api-table/compat-table/assets/icons/windows.svg'; import MacosIcon from '@/components/api-table/compat-table/assets/icons/macos-text.svg'; +import ClayIcon from '@/components/api-table/compat-table/assets/icons/clay.svg'; +import ReactlynxIcon from '@/components/api-table/compat-table/assets/icons/reactlynx.svg'; -const toPlatformName = (platform: string): PlatformName => { - switch (platform) { - case 'ios': - case 'ios-simulator': - case 'macos': - case 'macos-arm64': - case 'macos-intel': - return 'ios'; - case 'android': - return 'android'; - case 'web': - return 'web_lynx'; - default: - return 'web_lynx'; +const ICON_NAME_TO_URL: Record = { + apple: AppleIcon, + android: AndroidIcon, + harmony: HarmonyIcon, + web: WebIcon, + windows: WindowsIcon, + 'macos-text': MacosIcon, + clay: ClayIcon, + reactlynx: ReactlynxIcon, +}; + +const toIconUrl = (platformName: PlatformName | string): string => { + // Extra string ids used by tabs/badges that aren't in BCD.PlatformName. + if (platformName === 'clay') return ClayIcon; + if ( + platformName === 'macos' || + platformName === 'macos-arm64' || + platformName === 'macos-intel' + ) { + return MacosIcon; } + if (platformName === 'web') return WebIcon; + if (platformName === 'windows') return WindowsIcon; + + // BCD-known platform names route through compat-table's mapping so we stay + // consistent with the APITable headers (clay_macos → macos-text etc.). + const iconName = mapPlatformNameToIconName(platformName as PlatformName); + return ICON_NAME_TO_URL[iconName] ?? ClayIcon; }; export const PlatformSvg = ({ @@ -35,46 +50,11 @@ export const PlatformSvg = ({ className, key, }: { - // Accept extra string ids ('clay', 'macos', 'macos-arm64', 'macos-intel', - // 'windows') alongside the canonical PlatformName so PlatformTabs and - // ChoiceTabs can use the homepage-aligned icon set without TS friction. platformName: PlatformName | string; className?: string; key?: string; }) => { - var svgUrl; - if (platformName === 'clay') { - svgUrl = ClayIcon; - } else if ( - platformName === 'macos' || - platformName === 'macos-arm64' || - platformName === 'macos-intel' || - platformName === 'clay_macos' - ) { - // Use the dedicated "macOS" text mark so macOS is visually distinct from - // iOS (which both share the Apple glyph). - svgUrl = MacosIcon; - } else { - switch (mapPlatformNameToIconName(platformName)) { - case 'android': - svgUrl = AndroidIcon; - break; - case 'apple': - svgUrl = IosIcon; - break; - case 'harmony': - svgUrl = HarmonyIcon; - break; - case 'windows': - svgUrl = WindowsIcon; - break; - case 'web': - svgUrl = WebIcon; - break; - default: - svgUrl = ClayIcon; - } - } + const svgUrl = toIconUrl(platformName); return (
+ /> ); }; +const toPlatformName = (platform: string): PlatformName => { + switch (platform) { + case 'ios': + case 'ios-simulator': + case 'macos': + case 'macos-arm64': + case 'macos-intel': + return 'ios'; + case 'android': + return 'android'; + case 'web': + return 'web_lynx'; + default: + return 'web_lynx'; + } +}; + /** * Component for rendering platform icons */ From ca62974196caf19ce7364490b846d6d2ba3515df Mon Sep 17 00:00:00 2001 From: "xuan.huang" <5563315+Huxpro@users.noreply.github.com> Date: Wed, 3 Jun 2026 09:33:29 -0700 Subject: [PATCH 2/5] chore: drop now-unused home/ platform icon SVGs All consumers route through PlatformSvg backed by the compat-table icon set after the previous commit, so the home/ duplicates have no references left. Removes home-icon-android.svg, home-icon-apple.svg, home-icon-apple-dark.svg, home-icon-web.svg, plus the harmony/windows/clay copies that lived in two places. Change-Id: I477373262facabc57ce574b3a0e6c309bb0f1b00 --- docs/public/assets/home/clay.svg | 18 ------------------ docs/public/assets/home/harmony.svg | 1 - docs/public/assets/home/home-icon-android.svg | 7 ------- .../assets/home/home-icon-apple-dark.svg | 3 --- docs/public/assets/home/home-icon-apple.svg | 3 --- docs/public/assets/home/home-icon-web.svg | 3 --- docs/public/assets/home/windows.svg | 19 ------------------- 7 files changed, 54 deletions(-) delete mode 100644 docs/public/assets/home/clay.svg delete mode 100644 docs/public/assets/home/harmony.svg delete mode 100644 docs/public/assets/home/home-icon-android.svg delete mode 100644 docs/public/assets/home/home-icon-apple-dark.svg delete mode 100644 docs/public/assets/home/home-icon-apple.svg delete mode 100644 docs/public/assets/home/home-icon-web.svg delete mode 100644 docs/public/assets/home/windows.svg diff --git a/docs/public/assets/home/clay.svg b/docs/public/assets/home/clay.svg deleted file mode 100644 index 7da4dd1e3..000000000 --- a/docs/public/assets/home/clay.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/public/assets/home/harmony.svg b/docs/public/assets/home/harmony.svg deleted file mode 100644 index 0034e4c95..000000000 --- a/docs/public/assets/home/harmony.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/public/assets/home/home-icon-android.svg b/docs/public/assets/home/home-icon-android.svg deleted file mode 100644 index 9ac66982a..000000000 --- a/docs/public/assets/home/home-icon-android.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/docs/public/assets/home/home-icon-apple-dark.svg b/docs/public/assets/home/home-icon-apple-dark.svg deleted file mode 100644 index 8847642af..000000000 --- a/docs/public/assets/home/home-icon-apple-dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/public/assets/home/home-icon-apple.svg b/docs/public/assets/home/home-icon-apple.svg deleted file mode 100644 index d83d58646..000000000 --- a/docs/public/assets/home/home-icon-apple.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/public/assets/home/home-icon-web.svg b/docs/public/assets/home/home-icon-web.svg deleted file mode 100644 index 96842529e..000000000 --- a/docs/public/assets/home/home-icon-web.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/public/assets/home/windows.svg b/docs/public/assets/home/windows.svg deleted file mode 100644 index a997b733d..000000000 --- a/docs/public/assets/home/windows.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - windows [#174] - Created with Sketch. - - - - - - - - - - - - - \ No newline at end of file From 7e57ada79862f9c350a16876bb25b0e92e645f08 Mon Sep 17 00:00:00 2001 From: "xuan.huang" <5563315+Huxpro@users.noreply.github.com> Date: Wed, 3 Jun 2026 10:22:16 -0700 Subject: [PATCH 3/5] chore(icons): swap Android glyph back to the half-dome silhouette Replace the full Bugdroid body with the half-dome face that the homepage used to ship, retained as a single fill-rule="evenodd" path so the eyes become cutouts in the silhouette. Because every consumer renders the icon through mask-image + currentColor, the result is fully monochrome and inherits whatever color the parent sets, so callers can recolor it programmatically per surface (e.g. style={{ color }} or a scoped CSS rule) when needed. Change-Id: I666a542e9aa8005e804127a1851291e9206665c6 --- .../compat-table/assets/icons/android.svg | 33 +++---------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/src/components/api-table/compat-table/assets/icons/android.svg b/src/components/api-table/compat-table/assets/icons/android.svg index 0ad4277dc..873a2491a 100644 --- a/src/components/api-table/compat-table/assets/icons/android.svg +++ b/src/components/api-table/compat-table/assets/icons/android.svg @@ -1,28 +1,5 @@ - - - - - - - - - - - - - - \ No newline at end of file + + + + + From fb6b699d6155b81454e89190137218642c10a836 Mon Sep 17 00:00:00 2001 From: "xuan.huang" <5563315+Huxpro@users.noreply.github.com> Date: Wed, 3 Jun 2026 10:31:58 -0700 Subject: [PATCH 4/5] feat(home): tint feature-card platform icons with brand-adjacent hues Drop the uniform dark-grey wash on the homepage feature card and tint each platform icon with a hue that reads as native to the platform: zinc for Apple (iOS / macOS), emerald for Android, rose for HarmonyOS, orange for Web (HTML5), sky for Windows. All sit at Tailwind ~600 in light mode and ~400 in dark mode so saturation and tonal weight stay matched even though the hues span the wheel. Change-Id: Id6ca10297a8e6b38092ac4b5faff55d70f3b40f8 --- src/components/home-comps/features/icon.tsx | 17 ++++++++++++++++- .../home-comps/features/index.module.less | 1 - 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/components/home-comps/features/icon.tsx b/src/components/home-comps/features/icon.tsx index 3e196d1dc..9bedd36e1 100644 --- a/src/components/home-comps/features/icon.tsx +++ b/src/components/home-comps/features/icon.tsx @@ -1,12 +1,27 @@ import React from 'react'; import { withBase } from '@rspress/core/runtime'; +import { cn } from '@/lib/utils'; import { PlatformSvg } from '@/components/platform-navigation/PlatformIcon'; import ReactLynxIcon from '@/components/api-table/compat-table/assets/icons/reactlynx.svg?react'; import VueLynxIcon from '@assets/home/vue-lynx-logo.svg?react'; import styles from './index.module.less'; +// Each platform gets a brand-adjacent hue, kept at matching tonal weight +// (Tailwind ~600 in light mode, ~400 in dark) so the row stays harmonious. +const PLATFORM_TINT: Record = { + ios: 'text-zinc-700 dark:text-zinc-300', + macos: 'text-zinc-700 dark:text-zinc-300', + android: 'text-emerald-600 dark:text-emerald-400', + harmony: 'text-rose-600 dark:text-rose-400', + web: 'text-orange-600 dark:text-orange-400', + windows: 'text-sky-600 dark:text-sky-400', +}; + const PlatformIconWrapper = ({ platform }: { platform: string }) => ( - + ); const IconIOS = () => ; diff --git a/src/components/home-comps/features/index.module.less b/src/components/home-comps/features/index.module.less index aea5e6cc2..24a8a56d8 100644 --- a/src/components/home-comps/features/index.module.less +++ b/src/components/home-comps/features/index.module.less @@ -37,7 +37,6 @@ flex-direction: column; .platform-icon { --icon-size: 18px; - color: var(--home-blog-btn-color); } .reactlynx-icon { From 0ab02c744234224771f71c5cd35a99f46e715945 Mon Sep 17 00:00:00 2001 From: "xuan.huang" <5563315+Huxpro@users.noreply.github.com> Date: Wed, 3 Jun 2026 11:37:11 -0700 Subject: [PATCH 5/5] chore: trigger Netlify rebuild to triage compat-data 404 Change-Id: I0273c96570f5ac0df26d29521fe26e7a4544e31e