Icon Font Management
This directory contains scripts and resources for managing the Bitwarden icon font (BWI).
Overview
The icon system uses Figma-exported SVG files that are converted into a web font using Fantasticon. SVG filenames directly become CSS class names (with the bwi- prefix added automatically), making the workflow simple and straightforward.
Adding a New Icon
Follow these steps to add a new icon to the icon font:
1. Export the Icon from Figma
- Open the Figma icon file
- Select the icon you want to export
- Export as SVG with these settings:
- Outline stroke: Enabled
- Include "id" attribute: Disabled
- Simplify stroke: Enabled
- Name the file using kebab-case (e.g.,
help.svg,star-filled.svg,add-circle.svg) - Save the SVG file to
libs/assets/src/material-icons/
Important: The SVG filename directly becomes the CSS class name. For example, help.svg will generate the class bwi-help, and star-filled.svg will generate bwi-star-filled. Choose your filename carefully as it determines how developers will use the icon.
2. Generate the Icon Font
Run the build script:
npm run icons:build
This script will:
- ✅ Generate the icon font files from all SVGs (woff2, woff, ttf, svg)
- ✅ Update the SCSS with the new icon mappings
- ✅ Automatically update
libs/components/src/shared/icon.tswith the new icon - ✅ Clean up temporary build artifacts
Output files:
libs/angular/src/scss/bwicons/fonts/bwi-font.*- Font fileslibs/angular/src/scss/bwicons/styles/style.scss- Updated with new iconlibs/components/src/shared/icon.ts- Auto-generated TypeScript icon list (do not edit manually)
Note: The TypeScript icon array is now auto-generated during the build process. You no longer need to manually add icons to icon.ts.
3. Add to Storybook Documentation
Add your icon to the appropriate category in libs/components/src/stories/icons/icon-data.ts:
// Choose the appropriate category:
// - statusIndicators
// - bitwardenObjects
// - actions
// - directionalMenuIndicators
// - miscObjects
// - platformsAndLogos
const actions = [
// ... existing icons ...
{
id: "bwi-your-new-icon",
usage: "Detailed description of when and how to use this icon.",
},
];
Usage description guidelines:
- Start with what the icon indicates or does
- Include context-specific guidance (mobile, desktop, toggle states, etc.)
- Mention any variants or related icons
- Note any accessibility considerations
4. Test Your Icon
-
Visual verification: Run Storybook to see your icon
npm run storybookNavigate to "Documentation / Icons" to verify your icon appears correctly
-
Type checking: Ensure TypeScript compiles without errors
npm run test:types -
Usage test: Try using the icon in a component
<bit-icon icon="bwi-your-new-icon"></bit-icon>
Migrating Icon Names
Use the migration script when you need to rename icon references across the entire codebase. This is different from adding a new icon—it's for bulk-renaming existing icon class names.
When to Use Migration
- You're standardizing icon names to match new Figma conventions
- You're replacing a legacy icon name with a new one
- You need to update icon references in dozens or hundreds of files
Important: This is NOT for adding new icons. Use the "Adding a New Icon" workflow above for that.
How to Migrate Icon Names
1. Add the mapping to migration-map.ts
Open scripts/material-icons/migration-map.ts and add your mapping to the BWI_TO_FIGMA object:
export const BWI_TO_FIGMA: Record<string, string> = {
// ... existing mappings ...
// Add your migration here
"old-icon-name": "new-icon-name",
};
Example:
// Rename bwi-question-circle to bwi-help
"question-circle": "help",
// Rename bwi-spinner to bwi-loading
"spinner": "loading",
Note: Do not include the bwi- prefix—the script adds it automatically.
2. Preview the changes (recommended)
Run the migration script in dry-run mode to see what will be changed:
npm run icons:migrate -- --dry-run
This shows you all files and occurrences that will be updated without actually modifying anything.
3. Run the migration
Once you've verified the preview, run the actual migration:
npm run icons:migrate
4. Review the migration report
After migration completes, check scripts/material-icons/migration-report.json for a detailed report of all changes:
[
{
"file": "apps/web/src/app/components/icon.component.html",
"oldName": "bwi-question-circle",
"newName": "bwi-help",
"occurrences": 3
}
// ... more entries
]
What Gets Updated
The migration script searches and replaces icon names in:
- TypeScript files (
.ts) - HTML templates (
.html) - SCSS/CSS files (
.scss,.css) - Markdown documentation (
.md,.mdx)
In the following directories:
apps/libs/bitwarden_license/
Excluding build/cache directories like node_modules, dist, .git, etc.
Migration Workflow Example
Complete workflow for renaming an icon:
# 1. Add mapping to migration-map.ts
# "spinner": "loading"
# 2. Preview changes
npm run icons:migrate -- --dry-run
# 3. Run migration
npm run icons:migrate
# 4. Review migration-report.json
# 5. Commit the changes
git add .
git commit -m "Migrate bwi-spinner to bwi-loading"
File Structure
scripts/material-icons/
├── build-with-bwi-names.ts # Main build script
├── migrate-icon-names.ts # Migration script for bulk renames
├── migration-map.ts # Configuration for migration
├── migration-report.json # Generated migration report
└── README.md # This file
libs/assets/src/material-icons/
├── help.svg # Figma-exported SVG files
├── star-filled.svg
└── ... (all source SVG files)
libs/angular/src/scss/bwicons/
├── fonts/
│ ├── bwi-font.woff2 # Generated font files
│ ├── bwi-font.woff
│ ├── bwi-font.ttf
│ └── bwi-font.svg
└── styles/
└── style.scss # Generated SCSS with icon mappings
libs/components/src/
├── shared/
│ └── icon.ts # TypeScript icon types
└── stories/icons/
└── icon-data.ts # Storybook documentation
Icon Naming Conventions
The icon system uses a direct naming approach: the SVG filename becomes the CSS class name (with bwi- prefix added automatically).
Naming Guidelines
- Use kebab-case:
star-filled.svg, notstarFilled.svgorstar_filled.svg - Be descriptive: Choose names that clearly indicate the icon's purpose
- Follow Figma: Use names from the Figma design system when possible
- Consider usage: The filename determines how developers reference the icon
Examples
| SVG Filename | Generated CSS Class | Usage Example |
|---|---|---|
help.svg |
.bwi-help |
Help/question icons |
star-filled.svg |
.bwi-star-filled |
Filled star for favorites |
add-circle.svg |
.bwi-add-circle |
Add button with circle background |
arrow-filled-down.svg |
.bwi-arrow-filled-down |
Dropdown indicators |
visibility-off.svg |
.bwi-visibility-off |
Hide password toggle |
Legacy Mappings
Some icons have legacy mappings documented in migration-map.ts for historical reference. For example:
bwi-question-circlewas migrated tobwi-helpbwi-spinnerwas migrated tobwi-loadingbwi-pluswas migrated tobwi-add
These mappings are only relevant if you're running migrations. New icons don't need any mappings.
Troubleshooting
Icon not appearing after build
- Verify the SVG file is in
libs/assets/src/material-icons/ - Check that your SVG filename uses kebab-case and has the
.svgextension - Run
npm run icons:buildagain - Clear browser cache
Wrong icon displaying
- Verify the SVG filename matches what you expect (it becomes the CSS class)
- Ensure you're using the correct
bwi-class name in your component - Check for duplicate SVG files with similar names
Font not updating
- Delete the generated font files and rebuild:
rm libs/angular/src/scss/bwicons/fonts/bwi-font.* npm run icons:build
TypeScript errors
- Ensure you added the icon to
libs/components/src/shared/icon.ts - Check that the icon name format matches:
bwi-icon-name
Advanced Usage
Icon Sizing Classes
Available utility classes (defined in style.scss):
.bwi- Base class (required).bwi-sm- Small (0.875em).bwi-lg- Large (~1.33em).bwi-2x- 2x size.bwi-3x- 3x size.bwi-4x- 4x size.bwi-fw- Fixed width (~1.3em)
Rotation & Animation
.bwi-rotate-270- Rotate 270 degrees.bwi-spin- Animated spinning (for loading spinners)
Example Usage
<!-- Basic icon -->
<i class="bwi bwi-help"></i>
<!-- Large icon -->
<i class="bwi bwi-help bwi-lg"></i>
<!-- Fixed width icon (useful in lists) -->
<i class="bwi bwi-help bwi-fw"></i>
<!-- Spinning icon -->
<i class="bwi bwi-loading bwi-spin"></i>
Best Practices
- Icon Consistency: Follow the existing Figma design system naming
- Semantic Naming: Use descriptive filenames that clearly indicate the icon's purpose
- Documentation: Always add usage guidelines to Storybook
- Accessibility: Include proper ARIA labels when using icons without text
- SVG Optimization: Export from Figma with strokes outlined
- Testing: Verify icons in Storybook before committing
Resources
- Fantasticon Documentation
- Icon Font Best Practices
- Internal Figma Icon Library: [Link to your Figma file]
Support
For questions or issues:
- Check the troubleshooting section above
- Review existing icons in
libs/assets/src/material-icons/ - Consult the design team for icon naming conventions