Documentation

Everything you need to get started with AirQo Icons for React, Vue, and Flutter.

ReactVue 3Flutter

🚀 Installation

AirQo Icons provides packages for React, Vue, and Flutter. Choose your framework:

ReactReact Package

npm
npm install @airqo/icons-react
yarn
yarn add @airqo/icons-react
pnpm
pnpm add @airqo/icons-react

VueVue 3 Package

npm
npm install @airqo/icons-vue
yarn
yarn add @airqo/icons-vue
pnpm
pnpm add @airqo/icons-vue

FlutterFlutter Package

pubspec.yaml
dependencies:
  airqo_icons_flutter: ^1.0.1
Terminal
flutter pub get

Advanced Search Dependencies (React/Vue only)

To use advanced search utilities like AirQOIconsUtils.searchIcons or useIconSearch, install fuse.js:

npm
npm install fuse.js

🎯 Quick Start

Get up and running in seconds with your preferred framework:

React Example
import { AqHome01, AqUganda, AqBarChart01 } from '@airqo/icons-react';

function App() {
  return (
    <div className="flex items-center space-x-4">
      <AqUganda size={32} className="text-green-600" />
      <AqHome01 size={24} className="text-blue-600" />
      <AqBarChart01 size={28} className="text-purple-600" />
    </div>
  );
}

✅ Tree-shaking ensures only imported icons are bundled, keeping your app lightweight across all frameworks.

📋 API Reference

All icons accept these common props, extending standard SVG attributes:

TypeScript Interface
interface IconProps extends React.SVGProps<SVGSVGElement> {
  size?: number | string; // Icon size (default: 24)
  className?: string;     // CSS classes
  color?: string;         // Icon color (default: currentColor)
  // ... all standard SVG props (onClick, onMouseOver, etc.)
}
PropTypeDefaultDescription
sizenumber | string24Sets the width and height of the icon.
colorstringcurrentColorSets the fill/stroke color of the icon.
classNamestring-Applies custom CSS classes.
...propsSVGProps<SVGSVGElement>-All standard SVG attributes are supported (e.g., onClick, onMouseOver).

🎨 Styling Examples

Style icons using props or CSS classes for maximum flexibility.

Using Props

<AqHome01 size={32} color="#3B82F6" />
<AqSettings01 size="2rem" className="text-purple-500 hover:text-purple-700" />

CSS Classes & Tailwind

<AqUser01 className="w-8 h-8 text-blue-500 drop-shadow-md" />
<AqSearchLg className="w-6 h-6 text-gray-400 hover:text-gray-600 transition-colors" />

CSS Modules

styles.module.css
.icon {
  color: #3b82f6;
  transition: color 0.2s ease;
}
.icon:hover {
  color: #1d4ed8;
}
Component.tsx
import styles from './styles.module.css';
import { AqHome01 } from '@airqo/icons-react';

<AqHome01 className={styles.icon} />

Styled Components

import styled from 'styled-components';
import { AqHome01 } from '@airqo/icons-react';

const StyledIcon = styled(AqHome01)`
  color: ${props => props.theme.primary};
  transition: color 0.2s ease;
  &:hover {
    color: ${props => props.theme.primaryDark};
  }
`;

🔧 TypeScript Support

Full TypeScript support is built-in. Leverage types for props and create type-safe components.

import type { ComponentProps } from 'react';
import { AqHome01 } from '@airqo/icons-react';

// Type for icon props
type IconProps = ComponentProps<typeof AqHome01>;

// Type-safe custom component
interface ButtonWithIconProps {
  icon: React.ComponentType<ComponentProps<'svg'>>; // Accept any icon component
  children: React.ReactNode;
}

function ButtonWithIcon({ icon: Icon, children }: ButtonWithIconProps) {
  return (
    <button className="flex items-center space-x-2 p-2 hover:bg-gray-100 dark:hover:bg-gray-800 rounded">
      <Icon size={20} />
      <span>{children}</span>
    </button>
  );
}

// Usage
<ButtonWithIcon icon={AqHome01}>Home</ButtonWithIcon>

🖖 Vue 3 Package

AirQo Icons provides full Vue 3 support with Composition API and TypeScript integration.

Installation

Install Vue Package
npm install @airqo/icons-vue

Basic Usage

Single File Component
<template>
  <div class="flex items-center gap-4">
    <AqHome01 :size="24" class="text-blue-600" />
    <AqBarChart01 :size="32" color="#10b981" />
    <AqUganda :size="20" class="border rounded" />
  </div>
</template>

<script setup>
import { AqHome01, AqBarChart01, AqUganda } from '@airqo/icons-vue';
</script>

Props API

All Vue icon components accept these props:

Props Interface
interface IconProps {
  size?: number | string; // Default: 24
  color?: string; // Default: 'currentColor'
  class?: string; // CSS classes
}

Advanced Examples

Dynamic Icons

Dynamic Component
<template>
  <component 
    :is="iconComponent" 
    :size="24" 
    :color="iconColor" 
  />
</template>

<script setup>
import { ref, computed } from 'vue';
import { AqHome01, AqSettings01, AqUser01 } from '@airqo/icons-vue';

const iconName = ref('home');
const iconColor = ref('#6366f1');

const iconComponent = computed(() => {
  const iconMap = {
    home: AqHome01,
    settings: AqSettings01,
    user: AqUser01,
  };
  return iconMap[iconName.value] || AqHome01;
});
</script>

Theme-aware Icons

Responsive Theme
<template>
  <AqSun 
    :size="iconSize" 
    :color="isDark ? '#fbbf24' : '#f59e0b'" 
    class="transition-colors duration-200"
  />
</template>

<script setup>
import { ref, computed } from 'vue';
import { AqSun } from '@airqo/icons-vue';

const isDark = ref(false);
const iconSize = computed(() => window.innerWidth > 600 ? 32 : 24);
</script>

Framework Integration

Nuxt.js

pages/index.vue
<template>
  <div>
    <h1 class="flex items-center gap-2">
      <AqAirqo :size="32" />
      Air Quality Dashboard
    </h1>
    <AqBarChart01 :size="48" class="text-blue-500" />
  </div>
</template>

<script setup>
import { AqAirqo, AqBarChart01 } from '@airqo/icons-vue';
</script>

Vite + Vue 3

main.ts
import { createApp } from 'vue';
import App from './App.vue';

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

Performance Notes

  • • Bundle size: ~6.4MB total, ~4-6KB per icon
  • • Tree-shakable: Import only what you need
  • • SSR compatible: Works with Nuxt.js and SSR frameworks
  • • Vue 3.3+ with Composition API support

🧰 Utilities & Hooks

The package provides powerful utilities and React hooks for advanced icon management.

Utility Class: AirQOIconsUtils

Static methods for programmatic icon access and manipulation.

import { AirQOIconsUtils } from '@airqo/icons-react';

// Get all registered icons
const allIcons = AirQOIconsUtils.getAllIcons();

// Search icons by name, group, or tags
const searchResults = AirQOIconsUtils.searchIcons('chart', {
  maxResults: 10,
  groupFilter: ['Charts', 'General'],
});

// Intelligent search with suggestions
const intelligentResults = AirQOIconsUtils.intelligentSearch('user');
console.log(intelligentResults.exactMatches);
console.log(intelligentResults.fuzzyMatches);
console.log(intelligentResults.suggestions);

// Get all icon groups
const groups = AirQOIconsUtils.getAllGroups();

// Get icons by group
const chartIcons = AirQOIconsUtils.getIconsByGroup('Charts');

// Get icon metadata by name
const homeIcon = AirQOIconsUtils.getIcon('AqHome01');

// Get popular icons
const popularIcons = AirQOIconsUtils.getPopularIcons(20);

React Hooks

Convenient hooks for integrating icons into your React components.

useIconSearch

import { useIconSearch } from '@airqo/icons-react';
import { useState } from 'react';

function IconBrowser() {
  const [query, setQuery] = useState('');
  const { results, isLoading } = useIconSearch(query, {
    maxResults: 50,
    debounceMs: 300, // Wait 300ms after typing stops before searching
  });

  return (
    <div>
      <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search icons..." />
      {isLoading ? <div>Searching...</div> : (
        <div className="grid grid-cols-6 gap-4">
          {results.map((icon) => (
            <div key={icon.name} className="text-center">
              <icon.component size={32} />
              <span className="text-sm">{icon.name}</span>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

useIconGroups & useIconsByGroup

import { useIconGroups, useIconsByGroup } from '@airqo/icons-react';
import { useState } from 'react';

function GroupedIconBrowser() {
  const [selectedGroup, setSelectedGroup] = useState<string | null>(null);
  const { groups } = useIconGroups(); // Get all groups
  const { icons: groupIcons } = useIconsByGroup(selectedGroup || '', 'name'); // Get icons for selected group

  return (
    <div>
       <select onChange={(e) => setSelectedGroup(e.target.value || null)} value={selectedGroup || ''}>
        <option value="">All Groups</option>
        {groups.map(group => (
          <option key={group.name} value={group.name}>{group.displayName || group.name}</option>
        ))}
      </select>
      <div className="grid grid-cols-6 gap-4 mt-4">
        {groupIcons.map((icon) => (
          <div key={icon.name} className="text-center">
            <icon.component size={32} />
            <span className="text-sm">{icon.name}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

Other Useful Hooks

  • useIcon(iconName: string) - Fetch a single icon's metadata.
  • usePopularIcons(limit?: number) - Get a list of popular icons.
  • useSimilarIcons(iconName: string, limit?: number) - Find icons similar to a given one.

⚡ Performance & Optimization

Designed for optimal performance in modern web applications.

Tree-Shaking

Import only the icons you need to minimize bundle size.

// ✅ Recommended - Tree shakable
import { AqHome01, AqSettings01 } from '@airqo/icons-react';

// ❌ Avoid - Imports entire library (~6MB)
// import * as Icons from '@airqo/icons-react';

Bundle Size

  • Full package: ~6MB (Avoid direct full imports)
  • Per icon: ~2-4KB (when tree-shaken)
  • Typical usage (10-20 icons): ~50-100KB

Code Splitting (Advanced)

For very large applications, lazy-load icons dynamically.

import { lazy, Suspense } from 'react';

const AqHome01 = lazy(() => import('@airqo/icons-react').then((mod) => ({ default: mod.AqHome01 })));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <AqHome01 size={32} />
    </Suspense>
  );
}

💡 Examples

Practical examples demonstrating common use cases.

Reusable Icon Wrapper

Custom Icon Component
import type { ComponentProps } from 'react';
import { AqHome01 } from '@airqo/icons-react'; // Example base icon

interface CustomIconProps extends ComponentProps<'svg'> {
  icon: React.ComponentType<ComponentProps<'svg'>>; // Accept any icon component
  label?: string;
}

function CustomIcon({ icon: Icon, label, ...props }: CustomIconProps) {
  return (
    <span className="inline-flex items-center">
      <Icon {...props} />
      {label && <span className="ml-2">{label}</span>}
    </span>
  );
}

// Usage
<CustomIcon icon={AqHome01} label="Home" size={24} color="#3B82F6" />

Dynamic Icon Selection

Conditional Icon Rendering
import { AqHome01, AqUser01, AqSettings01 } from '@airqo/icons-react';
import type { ComponentProps } from 'react';

type IconName = 'home' | 'user' | 'settings';
const iconMap: Record<IconName, React.ComponentType<ComponentProps<'svg'>>> = {
  home: AqHome01,
  user: AqUser01,
  settings: AqSettings01,
};

interface DynamicIconProps extends ComponentProps<'svg'> {
  name: IconName;
}

function DynamicIcon({ name, ...props }: DynamicIconProps) {
  const IconComponent = iconMap[name];
  if (!IconComponent) {
    console.warn(`Icon '${name}' not found`);
    return null; // Or a fallback icon
  }
  return <IconComponent {...props} />;
}

// Usage
<DynamicIcon name="home" size={24} />
<DynamicIcon name="user" size={20} className="text-blue-500" />

Animated Icons

Using Framer Motion
import { AqRefreshCw } from '@airqo/icons-react';
import { motion } from 'framer-motion';

const spinTransition = {
  loop: Infinity,
  ease: "linear",
  duration: 1
};

<motion.div
  animate={{ rotate: 360 }}
  transition={spinTransition}
>
  <AqRefreshCw />
</motion.div>

📱 Flutter Package

AirQo Icons provides native Flutter widgets with full platform support (Android, iOS, Linux, macOS, Web, Windows).

Installation

pubspec.yaml
dependencies:
  airqo_icons_flutter: ^1.0.1
Install Dependencies
flutter pub get

Basic Usage

Import and Use
import 'package:airqo_icons_flutter/airqo_icons_flutter.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        AqUganda(size: 32, color: Colors.green),
        AqHome01(size: 24, color: Colors.blue),
        AqBarChart01(size: 28, color: Colors.purple),
      ],
    );
  }
}

API Reference

All icons accept these parameters:

Widget Parameters
Widget AqIconWidget({
  Key? key,                    // Widget key
  double size = 24.0,         // Icon size (default: 24.0)
  Color? color,               // Icon color (uses SVG default if null)
  String? semanticLabel,      // Accessibility label
})

Advanced Examples

Material Design Integration

App Bar and Navigation
// In App Bar
AppBar(
  leading: AqMenu01(color: Colors.white),
  title: Text('AirQo Dashboard'),
  actions: [
    IconButton(
      icon: AqNotificationSquare(color: Colors.white),
      onPressed: () => _showNotifications(),
    ),
  ],
)

// In Bottom Navigation
BottomNavigationBar(
  items: [
    BottomNavigationBarItem(
      icon: AqHome01(),
      label: 'Home',
    ),
    BottomNavigationBarItem(
      icon: AqBarChart01(),
      label: 'Analytics',
    ),
    BottomNavigationBarItem(
      icon: AqUser01(),
      label: 'Profile',
    ),
  ],
)

Responsive Icons

Responsive Design
class ResponsiveIcon extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    final iconSize = screenWidth > 600 ? 32.0 : 24.0;

    return AqHome01(
      size: iconSize,
      color: Theme.of(context).primaryColor,
    );
  }
}

Accessibility Support

Semantic Labels
// Provide semantic labels for screen readers
AqHome01(
  semanticLabel: 'Navigate to home screen',
)

// Use in semantic widgets
Semantics(
  button: true,
  hint: 'Tap to open settings',
  child: GestureDetector(
    onTap: _openSettings,
    child: AqSettings01(),
  ),
)

✨ Features

  • • 🎯 1,383 icons across 22 comprehensive categories
  • • 🏷️ Aq prefix naming convention (AqHome01, AqUser, etc.)
  • • 📱 Flutter 3.0+ compatible with latest framework features
  • • 🎨 Fully customizable - size, color, semantic labels
  • • 🌍 Global coverage - 196 country flags A-Z
  • • ⚡ Performance optimized - SVG-based with minimal overhead
  • • ♿ Accessibility ready - Built-in semantic label support

Need Help?

Check out these additional resources or reach out to our community.