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 @@
-
-
-
\ 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