npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@qklinglingba/react-svg-theme

v1.0.0

Published

React SVG 图标一键换色。把设计师给的 SVG 文件通过 `fill="currentColor"` 机制换色,不依赖多套图。

Readme

@qklinglingba/react-svg-theme

React SVG 图标一键换色。把设计师给的 SVG 文件通过 fill="currentColor" 机制换色,不依赖多套图。

安装

npm install @qklinglingba/react-svg-theme

使用

1. 准备 SVG 文件

让设计师在需要换色的元素上使用 fill="currentColor",不需要换色的正常写色值:

<!-- 要跟主题换色的 -->
<path fill="currentColor" d="..." />
<!-- 辅色(同色 + 透明度) -->
<circle fill="currentColor" fill-opacity="0.2" d="..." />
<!-- 不换色的(红色警告等) -->
<circle fill="#ff4d4f" d="..." />

如果 SVG 是写死颜色的,用 CLI 批量转换:

npx @qklinglingba/react-svg-theme convert src/assets/image --colors "#151b26,#1369da"

2. 颜色管理(项目本地实现)

包不绑定任何颜色管理方案。推荐用 React Context:

// src/theme/index.ts
export const MY_COLORS = {
  blue: '#1677ff',
  green: '#52c41a',
  orange: '#fa8c16',
} as const;

// src/theme/ThemeContext.tsx
import { createContext, useContext, useState } from 'react';

const ThemeContext = createContext({ colorHex: '#1677ff', setColor: (hex: string) => {} });
export const useTheme = () => useContext(ThemeContext);
export const ThemeProvider = ({ children, defaultColor = '#1677ff' }) => {
  const [colorHex, setColor] = useState(defaultColor);
  return <ThemeContext.Provider value={{ colorHex, setColor }}>{children}</ThemeContext.Provider>;
};
// src/app.tsx
root.render(
  <ThemeProvider defaultColor="#1677ff">
    <App />
  </ThemeProvider>
);

3. 使用 SvgIcon

import { SvgIcon } from '@qklinglingba/react-svg-theme';
import { useTheme } from '@/theme/ThemeContext';
import iconSrc from '@/assets/image/icon.svg';

function Page() {
  const { colorHex } = useTheme();

  return (
    <SvgIcon src={iconSrc} color={colorHex} size={48} />
  );
}

4. 切换颜色

function ColorPicker() {
  const { colorHex, setColor } = useTheme();

  return (
    <div style={{ display: 'flex', gap: 8 }}>
      {Object.entries(MY_COLORS).map(([name, hex]) => (
        <div
          key={name}
          onClick={() => setColor(hex)}
          style={{
            width: 32, height: 32, borderRadius: '50%',
            background: hex, cursor: 'pointer',
            border: colorHex === hex ? '3px solid #000' : '3px solid transparent',
          }}
        />
      ))}
    </div>
  );
}

颜色存在 React Context 中,全局共享。A 页面换色,B 页面自动同步——无需额外逻辑。

API

<SvgIcon>

加载 SVG 文件并替换颜色。

| 参数 | 类型 | 默认值 | 说明 | |---|---|---|---| | src | string | — | SVG 文件 URL(import 得到或直接传 URL) | | color | string | — | 目标颜色 hex,如 #1677ff | | size | number \| '100%' | — | 正方形简写;传 '100%' 表示填满父容器(父容器需有固定宽高) | | width | number | — | 宽度(传 size 时忽略) | | height | number | — | 高度(传 size 时忽略) | | mode | 'img' \| 'inline' | 'img' | 渲染模式 | | className | string | '' | 额外 class |

mode 详解:

| | img(默认) | inline | |---|---|---| | 渲染方式 | data URI → <img> | dangerouslySetInnerHTML 内联 SVG | | DOM 节点 | 1 个 <img> | SVG 所有路径展开为真实 DOM | | CSS 控制 | 只能控制容器尺寸 | 可控制每个路径样式 | | 大量图标 | ✅ 推荐 | ⚠️ 50 个以内 | | 浏览器兼容性 | 所有现代浏览器 | 所有现代浏览器 |

选择合适的模式:

  • 页面上一次性展示 50 个以上图标 → img 模式
  • 需要 CSS 动画/交互控制路径 → inline 模式
  • 不确定 → 用 img 模式,不会错

size="100%" 示例:

<div style={{ width: 24, height: 24 }}>
  <SvgIcon src={icon} color={colorHex} size="100%" mode="inline" />
</div>

性能说明

渲染开销

每次颜色切换时,所有图标重新执行 fill/stroke 替换 + 渲染。50 个图标总计约 20-50ms(纯 CPU,无网络),用户无感知。

图像大小限制

| 文件大小 | 表现 | 建议 | |---|---|---| | ≤ 30KB | 瞬间完成 | 随便用 | | 30KB ~ 80KB | ~50-100ms | 正常使用 | | 80KB ~ 300KB | ~200-500ms | 少量可用,不推荐大量使用 | | > 300KB | 秒级阻塞 | 不要用,改用多套图方案 |

大图场景正确的做法:用 CLI 在构建时预处理,输出多份已换好色的 SVG 文件,运行时直接 <img src={...}> 切换 URL,零 JS 开销。

缓存机制

  • fetch 结果缓存在模块级 Map 中,同一图标首次加载后不再发网络请求
  • 但是刷新页面后缓存清空,重新进入页面需重新 fetch(命中浏览器 HTTP 缓存)

渲染模式对比

| 场景 | 推荐模式 | |---|---| | ≤ 20 个图标 | 两者都行 | | 20 ~ 200 个图标 | img 模式 | | > 200 个图标 | img 模式 + 分页 / 虚拟滚动 | | 需要 CSS 动画/交互 | inline 模式 | | SSR(Next.js App Router 等) | img 模式,组件需标记 'use client' |

兼容性

| 环境 | 支持情况 | |---|---| | 现代浏览器(Chrome/Firefox/Safari/Edge) | ✅ | | React 18+ | ✅ | | Next.js Pages Router | ✅(需 'use client') | | Next.js App Router | ✅(需 'use client') | | Remix | ✅(需 'use client') | | React Native | ❌ 需要原生 DOM | | IE 11 | ❌ |

运行时仅依赖 fetchMapbtoa 等标准 Web API,无外部运行时依赖。

CLI

转换 SVG 文件中写死的颜色为 currentColor

# 替换所有颜色
npx @qklinglingba/react-svg-theme convert src/assets/image

# 只替换指定色号
npx @qklinglingba/react-svg-theme convert src/assets/image --colors "#151b26,#1369da"

原理

  1. 通过 import 拿到 SVG 文件的 URL
  2. SvgIcon 在浏览器端 fetch 文件内容
  3. 将所有 fill="currentColor" / stroke="currentColor" 替换为目标 hex 值
  4. 默认编码为 base64 data URI,通过 <img> 渲染
  5. mode="inline" 时直接内联 SVG
  6. 如果 SVG 缺少 viewBox,组件会自动从 width/height 推断补齐,确保跨构建工具兼容