@brightlocal/icons

中文文档
2.5.0发布于 2026/11/03MITTypeScriptESM + CJS近 30 天下载 2433

BrightLocal Design System Icons - Lucide defaults and custom icons

原始使用文档
文档目录36 节
  1. Overview
  2. Installation
  3. Usage
  4. 1. Direct Import (Recommended)
  5. 2. DynamicIcon Component
  6. 3. Custom BrightLocal Icons
  7. Component Props
  8. DynamicIcon Component
  9. Flag & Social Media Icons
  10. Benefits
  11. Adding Custom Icons
  12. Method 1: Using createLucideIcon (Recommended)
  13. Method 2: Plain SVG Component
  14. Examples
  15. Icon Gallery
  16. Database-Driven Icons
  17. Loading States
  18. Icon Naming Convention
  19. Performance Considerations
  20. Direct Imports vs DynamicIcon
  21. Bundle Size Impact
  22. Default Icon Properties
  23. Default Sizes by Icon Type
  24. TypeScript Support
  25. Accessibility
  26. Troubleshooting
  27. Icon not displaying
  28. TypeScript errors
  29. Bundle size too large
  30. Migration from Other Icon Libraries
  31. From React Icons
  32. From Heroicons
  33. Resources
  34. Contributing
  35. Adding Social Media Icons
  36. License

@brightlocal/icons

BrightLocal Design System Icons - Lucide defaults and custom icons

Overview

This package provides a unified icon system for the BrightLocal Design System, combining:

  • All 5000+ Lucide React icons (tree-shakeable)
  • Custom BrightLocal icons
  • Dynamic icon loading for database-driven UI
  • Full TypeScript support

Installation

pnpm add @brightlocal/icons

Usage

Best for tree-shaking - only imports the icons you use.

import { Check, Heart, Star } from "@brightlocal/icons";

<Check className="w-4 h-4" />
<Heart size={20} color="red" fill="red" />
<Star size={16} strokeWidth={2} />

2. DynamicIcon Component

For database-driven icon rendering with code-splitting. Icons are loaded dynamically only when used.

import { DynamicIcon } from "@brightlocal/icons";

// From database or CMS
const iconName = user.settings.preferredIcon; // "heart"
<DynamicIcon name={iconName} size={20} />

// Works with custom icons too
<DynamicIcon name="bright-local-logo" size={32} />

// With Suspense fallback (optional)
<React.Suspense fallback={<div className="w-6 h-6 animate-pulse bg-gray-200 rounded" />}>
  <DynamicIcon name={dbIconName} size={16} />
</React.Suspense>

3. Custom BrightLocal Icons

import { BrightLocalLogo } from "@brightlocal/icons";

<BrightLocalLogo className="h-8 w-8 text-blue-600" />;

Component Props

DynamicIcon Component

  • name: Icon name (kebab-case, e.g., "camera", "chevron-down", "bright-local-logo")
  • size: Icon size in pixels (default: 16)
  • color: Icon color (uses currentColor by default)
  • strokeWidth: Stroke width (default: 1.33)
  • All other SVG props

Flag & Social Media Icons

  • size: Icon size in pixels (default: 16)
  • className: CSS classes for styling
  • All standard SVG props

Benefits

  • Tree-shakeable: Only imports icons you use (with direct imports)
  • Type-safe: Full TypeScript support with autocomplete
  • Flexible: Multiple import patterns for different use cases
  • Lazy loading: DynamicIcon splits icons into separate chunks
  • Consistent: Unified API across all icons
  • Optimized: Minimal bundle impact

Adding Custom Icons

Compatible with DynamicIcon and follows Lucide's guidelines (16×16 canvas, 2px strokes).

// src/custom-icons/my-icon.tsx
import { createLucideIcon } from "@brightlocal/icons";

export const MyIcon = createLucideIcon("MyIcon", [
  ["path", { d: "M12 2v20M2 12h20", key: "cross" }],
  ["circle", { cx: "12", cy: "12", r: "3", key: "center" }],
]);

export default MyIcon;

Then add to dynamic imports:

// src/icons/dynamic-icon-imports.ts
const customIconImports = {
  "my-icon": () =>
    import("../custom-icons/my-icon.js").then((m) => ({
      default: m.MyIcon,
    })),
};

Method 2: Plain SVG Component

For icons that don't need dynamic loading.

// src/custom-icons/my-icon.tsx
import * as React from "react";

export const MyIcon = (props: React.SVGProps<SVGSVGElement>) => (
  <svg viewBox="0 0 16 16" fill="none" {...props}>
    <path d="M12 2v20M2 12h20" stroke="currentColor" strokeWidth={2} />
  </svg>
);

Examples

import { Check, X, Plus, Minus, Heart, Star } from "@brightlocal/icons";

const icons = [Check, X, Plus, Minus, Heart, Star];

<div className="grid grid-cols-6 gap-4">
  {icons.map((Icon, i) => (
    <Icon key={i} size={16} />
  ))}
</div>;

Database-Driven Icons

import { DynamicIcon } from "@brightlocal/icons";

// Icons stored in database
const features = [
  { id: 1, name: "Fast", icon: "zap" },
  { id: 2, name: "Secure", icon: "shield" },
  { id: 3, name: "Scalable", icon: "trending-up" },
];

<div className="grid grid-cols-3 gap-4">
  {features.map((feature) => (
    <div key={feature.id}>
      <DynamicIcon name={feature.icon} size={32} />
      <h3>{feature.name}</h3>
    </div>
  ))}
</div>;

Loading States

import { Loader2 } from "@brightlocal/icons";

<button disabled>
  <Loader2 className="mr-2 animate-spin" size={16} />
  Loading...
</button>;

Icon Naming Convention

When using DynamicIcon, icon names follow kebab-case format:

  • Lucide icons: Convert PascalCase to kebab-case
    • ChevronDown → "chevron-down"
    • AlertCircle → "alert-circle"
    • UserPlus → "user-plus"
  • Custom icons: Use kebab-case consistently
    • BrightLocalLogo → "bright-local-logo"

Performance Considerations

Direct Imports vs DynamicIcon

Use Direct Imports when:

  • Icons are known at build time
  • Maximum tree-shaking is desired
  • You want the smallest possible bundle
import { Camera, Heart } from "@brightlocal/icons";

Use DynamicIcon when:

  • Icon names come from database/API
  • You need code-splitting for large icon sets
  • Building configurable UI components
<DynamicIcon name={iconFromDatabase} />

Bundle Size Impact

  • Direct import: ~1-2KB per icon (tree-shaken)
  • DynamicIcon: ~4KB + icon loaded on demand

Default Icon Properties

All Lucide icons from @brightlocal/icons are wrapped with design system defaults:

PropertyDefaultDescription
size16Icon dimensions in pixels
strokeWidth1.33Matches Figma design specs
absoluteStrokeWidthtrueKeeps stroke consistent regardless of icon size

Default Sizes by Icon Type

Icon TypeDefault SizeUse Case
Lucide icons16pxUI elements, buttons, inputs
DynamicIcon16pxDatabase-driven icons
Flag icons16pxCountry/region indicators
Social Media icons16pxBrand logos, social links
// Lucide icons default to 16px with 1.33 strokeWidth
<Check />

// Explicit size — stroke stays consistent (absoluteStrokeWidth: true)
<Check size={20} />
<Check size={12} />

TypeScript Support

Full TypeScript support with type inference:

import { DynamicIcon } from "@brightlocal/icons";
import type { DynamicIconProps } from "@brightlocal/icons";

// Props are fully typed
const props: DynamicIconProps = {
  name: "heart",
  size: 16,
  color: "#ff0000",
};

Accessibility

Icons should include proper accessibility attributes:

// Decorative icons (no semantic meaning)
<Check aria-hidden="true" />

// Meaningful icons (provide label)
<Heart aria-label="Like this post" role="img" />

// Interactive icons (use with button/link)
<button aria-label="Close dialog">
  <X size={20} />
</button>

Troubleshooting

Icon not displaying

  1. Check the icon name is correct (case-sensitive for direct imports)
  2. Verify the icon exists in Lucide library
  3. For DynamicIcon, ensure the icon is registered in dynamic-icon-imports.ts

TypeScript errors

Make sure you have the latest types installed:

pnpm add -D @types/react

Bundle size too large

Use direct imports instead of importing everything:

// ❌ Don't do this
import * as Icons from "@brightlocal/icons";

// ✅ Do this
import { Camera, Heart, Star } from "@brightlocal/icons";

Migration from Other Icon Libraries

From React Icons

// Before (react-icons)
import { FaHeart } from "react-icons/fa";
<FaHeart size={16} />;

// After (brightlocal/icons)
import { Heart } from "@brightlocal/icons";
<Heart size={16} />;

From Heroicons

// Before (heroicons)
import { HeartIcon } from "@heroicons/react/16/outline";
<HeartIcon className="h-6 w-6" />;

// After (brightlocal/icons)
import { Heart } from "@brightlocal/icons";
<Heart className="h-6 w-6" />;

Resources

Contributing

To add new custom icons:

  1. Create icon file in src/custom-icons/
  2. Export from src/index.ts
  3. Add to dynamic imports in src/icons/dynamic-icon-imports.ts
  4. Update customIconsData in Storybook documentation
  5. Run build: pnpm build

Adding Social Media Icons

Social media icons live in src/social-media/ with an auto-generated barrel (index.ts). The SourceLogo component in @brightlocal/ui-components resolves icon names automatically by convention (name → <PascalName>Original / <PascalName>Neutral), so most new icons work without any code change in ui-components.

When to add an alias: if the consumer-facing source key doesn't match the icon file stem (e.g. consumers pass "twitter" but the icon file is x-ex-twitter-original.tsx), add an entry to SOURCE_ICON_ALIASES in packages/ui-components/src/components/source-logo.tsx.

License

Part of the BrightLocal Design System. See main repository for license details.

版本与发布记录

@brightlocal/icons 共发布 14 个版本,首次发布于 2025/11/17;过去 12 个月发布了 14 个版本。

版本发布日期距今
2.5.0latest2026/11/035 天前
2.4.12026/10/1623 天前
2.4.02026/08/282 个月前
2.3.12026/06/254 个月前
2.3.02026/06/045 个月前
2.2.02026/05/285 个月前

关于 @brightlocal/icons 的常见问题

@brightlocal/icons 是什么?

BrightLocal Design System Icons - Lucide defaults and custom icons

如何安装 @brightlocal/icons?

在项目目录运行 npm install @brightlocal/icons,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^17.0.0 || ^18.0.0 || ^19.0.0)、react-dom(^17.0.0 || ^18.0.0 || ^19.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@brightlocal/icons 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@brightlocal/icons 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@brightlocal/icons 可以商用吗?

@brightlocal/icons 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@brightlocal/icons 的下载量有多少?

根据 npm 官方下载统计,@brightlocal/icons 在 2026/10/09 – 2026/11/07 这 30 天内被下载 2,433 次,日均约 81 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@brightlocal/icons 还在维护吗?

最新版本 2.5.0 发布于 2026/11/03(5 天前);至今共发布 14 个版本,其中过去 12 个月发布了 14 个;首次发布于 2025/11/17。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。