CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tabler--icons

Comprehensive ecosystem of 5,945 free MIT-licensed SVG icons with framework components for React, Vue, Svelte and raw SVG files.

Pending
Overview
Eval results
Files

vue-components.mddocs/

Vue Components

Vue component library providing tree-shakable components for all 5,945 Tabler Icons with full Vue 3 support. Each icon is available as an optimized Vue component with reactive props and consistent interfaces.

Package Information

  • Package Name: @tabler/icons-vue
  • Installation: npm install @tabler/icons-vue
  • Peer Dependencies: Vue >= 3.0.1

Core Imports

<script setup>
import { IconHome, IconHeart, IconArrowLeft } from '@tabler/icons-vue';
</script>

Or with Options API:

<script>
import { IconHome, IconHeart, IconArrowLeft } from '@tabler/icons-vue';

export default {
  components: { IconHome, IconHeart, IconArrowLeft }
};
</script>

Capabilities

Icon Component Import

Tree-shakable imports for individual icon components with full Vue 3 composition and options API support.

/**
 * Individual icon component imports
 * Pattern: Icon{PascalCaseName} for outline icons
 * Pattern: Icon{PascalCaseName}Filled for filled icons
 */
import { IconHome } from '@tabler/icons-vue';
import { IconHeart } from '@tabler/icons-vue';  
import { IconHeartFilled } from '@tabler/icons-vue';
import { IconArrowLeft } from '@tabler/icons-vue';

interface IconProps {
  /** Icon size in pixels (applies to both width and height) */
  size?: string | number;
  /** Icon stroke color (outline icons) or fill color (filled icons) */
  color?: string;
  /** Alias for color prop */
  stroke?: string;
  /** Stroke width for outline icons */
  strokeWidth?: string | number;
  /** CSS class name */
  class?: string;
  /** Inline styles */
  style?: string | object;
}

Usage Examples:

<template>
  <div>
    <!-- Basic usage -->
    <IconHome />
    
    <!-- With custom props -->
    <IconHeart 
      size="32" 
      color="red" 
      stroke-width="1.5"
      class="heart-icon"
    />
    
    <!-- With event handlers -->
    <IconArrowLeft 
      size="24" 
      @click="goBack"
      style="cursor: pointer"
    />
    
    <!-- Reactive props -->
    <IconHome 
      :size="iconSize"
      :color="theme.primary"
      :stroke-width="strokeWidth"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { IconHome, IconHeart, IconArrowLeft } from '@tabler/icons-vue';

const iconSize = ref(24);
const strokeWidth = ref(2);
const theme = { primary: '#3b82f6' };

const goBack = () => {
  history.back();
};
</script>

Icon Component Props

Comprehensive prop interface for customizing icon appearance and behavior with Vue reactivity.

interface IconProps {
  /** 
   * Icon size in pixels (applies to both width and height)
   * @default 24
   */
  size?: string | number;
  
  /** 
   * Icon stroke color (outline icons) or fill color (filled icons)
   * @default "currentColor"
   */
  color?: string;
  
  /** 
   * Alias for color prop - icon stroke color
   * @default "currentColor"
   */
  stroke?: string;
  
  /** 
   * Stroke width for outline icons
   * @default 2
   */
  strokeWidth?: string | number;
  
  /** 
   * CSS class name applied to the SVG element
   * Can be string or reactive ref
   */
  class?: string;
  
  /** 
   * Inline styles applied to the SVG element
   * Can be string, object, or reactive ref
   */
  style?: string | Record<string, any>;
}

Usage Examples:

<template>
  <div>
    <!-- Size variations -->
    <IconUser size="16" />  <!-- Small -->
    <IconUser size="24" />  <!-- Default -->
    <IconUser size="32" />  <!-- Large -->
    <IconUser :size="dynamicSize" /> <!-- Reactive -->
    
    <!-- Color variations -->
    <IconSettings color="#3b82f6" />
    <IconSettings stroke="rgb(239, 68, 68)" />
    <IconSettings :color="themeColor" />
    
    <!-- Stroke width -->
    <IconHome stroke-width="1" />   <!-- Thin -->
    <IconHome stroke-width="3" />   <!-- Thick -->
    <IconHome :stroke-width="weight" /> <!-- Reactive -->
    
    <!-- CSS classes -->
    <IconSettings class="settings-icon rotating" />
    <IconSettings :class="{ active: isActive }" />
    
    <!-- Inline styles -->
    <IconSettings style="cursor: pointer; transition: transform 0.2s;" />
    <IconSettings :style="{ color: isError ? 'red' : 'blue' }" />
    
    <!-- Event handlers -->
    <IconSettings 
      @click="toggleSettings"
      @mouseenter="onHover"
      @mouseleave="onLeave"
    />
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';
import { IconUser, IconSettings, IconHome } from '@tabler/icons-vue';

const dynamicSize = ref(24);
const weight = ref(2);
const isActive = ref(false);
const isError = ref(false);

const themeColor = computed(() => isActive.value ? '#3b82f6' : '#6b7280');

const toggleSettings = () => {
  console.log('Settings toggled');
};

const onHover = () => {
  console.log('Icon hovered');
};

const onLeave = () => {
  console.log('Icon left');
};
</script>

Outline vs Filled Variants

Access to both outline (stroke-based) and filled (solid) icon variants with different naming conventions.

/**
 * Icon naming conventions:
 * - Outline icons: Icon{PascalCaseName} (default style)
 * - Filled icons: Icon{PascalCaseName}Filled
 * 
 * Examples:
 * - IconHome (outline) vs IconHomeFilled (filled)
 * - IconHeart (outline) vs IconHeartFilled (filled)
 * - IconStar (outline) vs IconStarFilled (filled)
 */

// Outline icons (4,964 available)
import { 
  IconHome,
  IconHeart, 
  IconStar,
  IconUser,
  IconSettings
} from '@tabler/icons-vue';

// Filled icons (981 available) 
import {
  IconHomeFilled,
  IconHeartFilled,
  IconStarFilled,
  IconUserFilled,
  IconSettingsFilled
} from '@tabler/icons-vue';

Usage Examples:

<template>
  <div>
    <!-- Toggle between outline and filled -->
    <button @click="toggleFavorite">
      <IconHeartFilled v-if="isFavorite" color="red" />
      <IconHeart v-else color="gray" />
    </button>
    
    <!-- Star rating component -->
    <div class="rating">
      <template v-for="value in [1, 2, 3, 4, 5]" :key="value">
        <button @click="setRating(value)">
          <IconStarFilled v-if="value <= rating" color="gold" />
          <IconStar v-else color="gray" />
        </button>
      </template>
    </div>
    
    <!-- Conditional icon rendering -->
    <component 
      :is="isCompleted ? IconCheckCircleFilled : IconCheckCircle"
      :color="isCompleted ? 'green' : 'gray'"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { 
  IconHeart, 
  IconHeartFilled,
  IconStar,
  IconStarFilled,
  IconCheckCircle,
  IconCheckCircleFilled
} from '@tabler/icons-vue';

const isFavorite = ref(false);
const rating = ref(0);
const isCompleted = ref(false);

const toggleFavorite = () => {
  isFavorite.value = !isFavorite.value;
};

const setRating = (value) => {
  rating.value = value;
};
</script>

Vue 3 Composition API Integration

Deep integration with Vue 3's Composition API for reactive icon properties and dynamic behavior.

/**
 * Vue 3 Composition API integration patterns
 * Icons work seamlessly with refs, computed properties, and watchers
 */

// Reactive icon properties
import { ref, computed, watch } from 'vue';

// Example composable for icon theme
function useIconTheme() {
  const isDark = ref(false);
  const iconColor = computed(() => isDark.value ? '#ffffff' : '#000000');
  const iconSize = computed(() => isDark.value ? 28 : 24);
  
  return { isDark, iconColor, iconSize };
}

// Example composable for icon animation
function useIconAnimation() {
  const isAnimating = ref(false);
  const rotation = ref(0);
  
  const startAnimation = () => {
    isAnimating.value = true;
    rotation.value += 360;
  };
  
  return { isAnimating, rotation, startAnimation };
}

Usage Examples:

<template>
  <div>
    <!-- Theme-aware icons -->
    <IconSun 
      v-if="!isDark" 
      :color="iconColor" 
      :size="iconSize"
      @click="toggleTheme"
    />
    <IconMoon 
      v-else 
      :color="iconColor" 
      :size="iconSize"
      @click="toggleTheme"
    />
    
    <!-- Animated loading icon -->
    <IconLoader 
      :style="{ 
        transform: `rotate(${rotation}deg)`,
        transition: 'transform 0.5s ease'
      }"
      :class="{ spinning: isLoading }"
    />
    
    <!-- Status-based icons -->
    <IconCheck 
      v-if="status === 'success'"
      color="green" 
      :size="statusIconSize"
    />
    <IconX 
      v-else-if="status === 'error'"
      color="red" 
      :size="statusIconSize"
    />
    <IconClock 
      v-else
      color="gray" 
      :size="statusIconSize"
    />
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue';
import { 
  IconSun, 
  IconMoon, 
  IconLoader,
  IconCheck,
  IconX,
  IconClock
} from '@tabler/icons-vue';

// Theme composable
const isDark = ref(false);
const iconColor = computed(() => isDark.value ? '#ffffff' : '#000000');
const iconSize = computed(() => isDark.value ? 28 : 24);

const toggleTheme = () => {
  isDark.value = !isDark.value;
};

// Animation state
const isLoading = ref(false);
const rotation = ref(0);

watch(isLoading, (loading) => {
  if (loading) {
    const interval = setInterval(() => {
      rotation.value += 90;
    }, 200);
    
    // Cleanup on stop loading
    watch(() => !loading, () => clearInterval(interval), { once: true });
  }
});

// Status management
const status = ref('pending'); // 'success' | 'error' | 'pending'
const statusIconSize = computed(() => {
  return status.value === 'success' ? 32 : 24;
});
</script>

<style scoped>
.spinning {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
</style>

Template Integration Patterns

Common patterns for using icons within Vue templates with directives and computed properties.

/**
 * Vue template integration patterns
 * Advanced usage with v-model, v-for, v-if, and other directives
 */

// Dynamic icon selection
interface IconConfig {
  name: string;
  component: any;
  props?: Record<string, any>;
}

// Icon registry for dynamic rendering
const iconRegistry = {
  home: IconHome,
  user: IconUser,
  settings: IconSettings,
  // ... more icons
};

Usage Examples:

<template>
  <div>
    <!-- Dynamic icon rendering with v-for -->
    <div class="icon-grid">
      <div 
        v-for="icon in icons" 
        :key="icon.name"
        class="icon-card"
        @click="selectIcon(icon)"
      >
        <component 
          :is="icon.component"
          :size="icon.size || 24"
          :color="icon.color || 'currentColor'"
        />
        <span>{{ icon.name }}</span>
      </div>
    </div>
    
    <!-- Conditional icon rendering -->
    <div class="status-indicator">
      <IconCheck v-if="isValid" color="green" />
      <IconX v-else-if="hasError" color="red" />
      <IconLoader v-else class="spinning" />
    </div>
    
    <!-- Icon with v-model integration -->
    <div class="rating-input">
      <template v-for="star in 5" :key="star">
        <IconStarFilled 
          v-if="star <= rating"
          color="gold" 
          @click="rating = star"
        />
        <IconStar 
          v-else
          color="gray"
          @click="rating = star"
        />
      </template>
    </div>
    
    <!-- Icon button with slot content -->
    <button class="icon-button" @click="handleAction">
      <IconPlus size="16" />
      <span>{{ buttonText }}</span>
    </button>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';
import { 
  IconHome,
  IconUser, 
  IconSettings,
  IconCheck,
  IconX,
  IconLoader,
  IconStar,
  IconStarFilled,
  IconPlus
} from '@tabler/icons-vue';

// Dynamic icons
const icons = ref([
  { name: 'Home', component: IconHome, size: 32 },
  { name: 'User', component: IconUser, color: '#3b82f6' },
  { name: 'Settings', component: IconSettings },
]);

const selectIcon = (icon) => {
  console.log('Selected:', icon.name);
};

// Status management
const isValid = ref(false);
const hasError = ref(false);

// Rating with v-model
const rating = ref(0);

// Button state
const buttonText = computed(() => 
  rating.value > 0 ? 'Update Rating' : 'Add Rating'
);

const handleAction = () => {
  console.log('Action triggered with rating:', rating.value);
};
</script>

<style scoped>
.icon-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  gap: 1rem;
}

.icon-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 1rem;
  border: 1px solid #e5e7eb;
  border-radius: 0.5rem;
  cursor: pointer;
  transition: background-color 0.2s;
}

.icon-card:hover {
  background-color: #f9fafb;
}

.status-indicator {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.rating-input {
  display: flex;
  gap: 0.25rem;
}

.rating-input svg {
  cursor: pointer;
  transition: transform 0.1s;
}

.rating-input svg:hover {
  transform: scale(1.1);
}

.icon-button {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  border: none;
  border-radius: 0.25rem;
  background-color: #3b82f6;
  color: white;
  cursor: pointer;
  transition: background-color 0.2s;
}

.icon-button:hover {
  background-color: #2563eb;
}

.spinning {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
</style>

Common Usage Patterns

Icon Composables

Create reusable composables for common icon functionality and state management.

<script setup>
import { ref, computed } from 'vue';
import { IconHeart, IconHeartFilled } from '@tabler/icons-vue';

// Favorite toggle composable
function useFavorite(initialState = false) {
  const isFavorite = ref(initialState);
  
  const toggleFavorite = () => {
    isFavorite.value = !isFavorite.value;
  };
  
  const FavoriteIcon = computed(() => 
    isFavorite.value ? IconHeartFilled : IconHeart
  );
  
  const favoriteProps = computed(() => ({
    color: isFavorite.value ? 'red' : 'gray',
    size: 20
  }));
  
  return {
    isFavorite,
    toggleFavorite,
    FavoriteIcon,
    favoriteProps
  };
}

// Usage
const { isFavorite, toggleFavorite, FavoriteIcon, favoriteProps } = useFavorite();
</script>

<template>
  <button @click="toggleFavorite">
    <component :is="FavoriteIcon" v-bind="favoriteProps" />
    {{ isFavorite ? 'Favorited' : 'Favorite' }}
  </button>
</template>

Icon Provider Pattern

Create icon provider components for consistent theming and configuration.

<!-- IconProvider.vue -->
<template>
  <div class="icon-provider" :class="themeClass">
    <slot :iconProps="iconProps" :theme="theme" />
  </div>
</template>

<script setup>
import { computed, provide } from 'vue';

const props = defineProps({
  theme: {
    type: String,
    default: 'light'
  },
  size: {
    type: [String, Number],
    default: 24
  },
  strokeWidth: {
    type: [String, Number],
    default: 2
  }
});

const themeClass = computed(() => `icon-theme-${props.theme}`);

const iconProps = computed(() => ({
  size: props.size,
  strokeWidth: props.strokeWidth,
  color: props.theme === 'dark' ? '#ffffff' : '#000000'
}));

// Provide theme context
provide('iconTheme', {
  theme: props.theme,
  iconProps: iconProps.value
});
</script>

<style scoped>
.icon-theme-dark {
  background-color: #1f2937;
  color: #ffffff;
}

.icon-theme-light {
  background-color: #ffffff;
  color: #000000;
}
</style>

Performance Optimization

Best practices for optimizing icon performance in Vue applications.

<script setup>
import { ref, shallowRef, defineAsyncComponent } from 'vue';

// Lazy load icons for better performance
const LazyIconHome = defineAsyncComponent(() => 
  import('@tabler/icons-vue').then(mod => ({ default: mod.IconHome }))
);

// Icon registry with lazy loading
const iconComponents = shallowRef({});

const loadIcon = async (iconName) => {
  if (!iconComponents.value[iconName]) {
    const module = await import('@tabler/icons-vue');
    iconComponents.value[iconName] = module[iconName];
  }
  return iconComponents.value[iconName];
};

// Preload commonly used icons
const preloadIcons = async () => {
  const commonIcons = ['IconHome', 'IconUser', 'IconSettings'];
  await Promise.all(commonIcons.map(loadIcon));
};

// Call on component mount
preloadIcons();
</script>

<template>
  <div>
    <!-- Lazy loaded icon -->
    <Suspense>
      <LazyIconHome />
      <template #fallback>
        <div class="icon-placeholder" />
      </template>
    </Suspense>
    
    <!-- Dynamic icon loading -->
    <component 
      v-if="iconComponents[selectedIcon]"
      :is="iconComponents[selectedIcon]"
      v-bind="iconProps"
    />
  </div>
</template>

Install with Tessl CLI

npx tessl i tessl/npm-tabler--icons

docs

index.md

metadata.md

react-components.md

svelte-components.md

svg-data.md

svg-files.md

vue-components.md

tile.json