Skip to content

Icon System Setup Example

Complete step-by-step example for setting up the icon system in your project.

Project Structure

your-project/
├── public/
│   └── svg-icons.svg          # Project-specific icons
├── src/
│   ├── main.js
│   ├── App.vue
│   └── components/
│       └── MyComponent.vue
└── package.json

Step 1: Create Project Sprite File

Create public/svg-icons.svg:

svg
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <!-- Project-specific icons (no prefix needed) -->
    <symbol id="dashboard" viewBox="0 0 24 24" fill="none">
      <path d="M3 3h8v18H3V3zm10 0h8v18h-8V3z" stroke="currentColor" stroke-width="2"/>
    </symbol>
    
    <symbol id="reports" viewBox="0 0 24 24" fill="none">
      <path d="M12 2v20M2 12h20" stroke="currentColor" stroke-width="2"/>
    </symbol>
    
    <symbol id="settings" viewBox="0 0 24 24" fill="none">
      <circle cx="12" cy="12" r="3" stroke="currentColor" stroke-width="2"/>
      <path d="M12 1v6m0 6v6" stroke="currentColor" stroke-width="2"/>
    </symbol>
  </defs>
</svg>

Step 2: Register Sprites in main.js

src/main.js:

javascript
import { createApp } from 'vue';
import { registerSprite, setDefaultSprite } from '@ftx/ui';
import App from './App.vue';

// Register library common icons sprite (optional)
// If you copy common-icons.svg to public/icons/
registerSprite('/icons/common-icons.svg', {
  prefix: 'ftx-',
  priority: 10 // Higher priority (lower number)
});

// Register your project sprite (no prefix for project icons)
registerSprite('/svg-icons.svg', {
  prefix: '', // No prefix - these are project icons
  priority: 20
});

const app = createApp(App);
app.mount('#app');

Step 3: Use Icons in Components

src/components/MyComponent.vue:

vue
<template>
  <div class="icon-examples">
    <!-- Quasar Material icon (explicit with material: prefix) -->
    <FTxIcon name="material:home" size="24px" color="primary" />
    
    <!-- Library icon (ftx: prefix) -->
    <FTxIcon name="ftx:column" svg-size="24px" />
    
    <!-- Project icon (no prefix) -->
    <FTxIcon name="dashboard" svg-size="24px" />
  </div>
</template>

<script setup>
import { FTxIcon } from '@ftx/ui';
</script>

<style scoped>
.icon-examples {
  display: flex;
  gap: 16px;
  align-items: center;
}
</style>

Step 4: Adding New Icons

Add Project Icon (No Build Needed!)

  1. Edit public/svg-icons.svg:
svg
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <!-- Existing icons... -->
    
    <!-- New icon (no prefix needed for project icons) -->
    <symbol id="new-feature" viewBox="0 0 24 24" fill="none">
      <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" fill="currentColor"/>
    </symbol>
  </defs>
</svg>
  1. Save the file

  2. Refresh browser - icon is immediately available!

vue
<FTxIcon name="new-feature" svg-size="24px" />

Complete Example: E-commerce Project

Project Structure

ecommerce-app/
├── public/
│   ├── svg-icons.svg          # General icons
│   └── icons/
│       ├── nav-icons.svg      # Navigation icons
│       └── action-icons.svg   # Action button icons
├── src/
│   └── main.js

Sprite Files

public/svg-icons.svg:

svg
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <symbol id="cart" viewBox="0 0 24 24" fill="none">
      <path d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z" stroke="currentColor" stroke-width="2"/>
    </symbol>
    
    <symbol id="wishlist" viewBox="0 0 24 24" fill="none">
      <path d="M20.84 4.61a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 00-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 000-7.78z" stroke="currentColor" stroke-width="2"/>
    </symbol>
  </defs>
</svg>

public/icons/nav-icons.svg:

svg
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <symbol id="nav-home" viewBox="0 0 24 24" fill="none">
      <path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z" stroke="currentColor" stroke-width="2"/>
    </symbol>
    
    <symbol id="nav-products" viewBox="0 0 24 24" fill="none">
      <path d="M6 2L3 6v14a2 2 0 002 2h14a2 2 0 002-2V6l-3-4z" stroke="currentColor" stroke-width="2"/>
    </symbol>
  </defs>
</svg>

Registration

src/main.js:

javascript
import { createApp } from 'vue';
import { registerSprite, setDefaultSprite } from '@ftx/ui';
import App from './App.vue';

// Common icons (library)
registerSprite('/icons/common-icons.svg', {
  prefix: 'ftx-',
  priority: 10
});

// Navigation icons
registerSprite('/icons/nav-icons.svg', {
  prefix: 'nav-',
  priority: 20
});

// General project icons (no prefix)
registerSprite('/svg-icons.svg', {
  prefix: '', // No prefix - these are project icons
  priority: 30
});

const app = createApp(App);
app.mount('#app');

Usage

vue
<template>
  <div>
    <!-- Library icon -->
    <FTxIcon name="ftx:column" svg-size="24px" />
    
    <!-- Navigation icons -->
    <FTxIcon name="nav-home" svg-size="24px" />
    <FTxIcon name="nav-products" svg-size="24px" />
    
    <!-- General icons -->
    <FTxIcon name="cart" svg-size="24px" />
    <FTxIcon name="wishlist" svg-size="24px" />
  </div>
</template>

<script setup>
import { FTxIcon } from '@ftx/ui';
</script>

Migration from Existing Setup

If You Have SvgIconComponent

Before:

vue
<SvgIconComponent icon="table-column" />

After:

  1. Keep your existing sprite file (public/svg-icons.svg)
  2. Register it:
    javascript
    setDefaultSprite('/svg-icons.svg');
  3. Replace component:
    vue
    <FTxIcon name="table-column" svg-size="24px" />

If You Have Individual SVG Files

  1. Combine into sprite:

    svg
    <svg xmlns="http://www.w3.org/2000/svg">
      <defs>
        <symbol id="icon1" viewBox="0 0 24 24">...</symbol>
        <symbol id="icon2" viewBox="0 0 24 24">...</symbol>
      </defs>
    </svg>
  2. Register sprite:

    javascript
    setDefaultSprite('/svg-icons.svg');
  3. Update usage:

    vue
    <!-- Old -->
    <img src="/icons/icon1.svg" />
    
    <!-- New -->
    <FTxIcon name="icon1" svg-size="24px" />

Tips

  1. Organize by Feature: Create separate sprites for navigation, actions, status, etc.
  2. Use Prefixes: Prefix icons to avoid conflicts (e.g., nav-, action-)
  3. Optimize SVGs: Remove unnecessary attributes, optimize paths
  4. Use currentColor: Always use currentColor for fill/stroke
  5. Consistent viewBox: Use 0 0 24 24 for consistency

Released under the MIT License.