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

svelte-components.mddocs/

Svelte Components

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

Package Information

  • Package Name: @tabler/icons-svelte
  • Installation: npm install @tabler/icons-svelte
  • Peer Dependencies: Svelte >= 3 < 6 || >= 5.0.0-next.0

Core Imports

import { IconHome, IconHeart, IconArrowLeft } from '@tabler/icons-svelte';

Capabilities

Icon Component Import

Tree-shakable imports for individual icon components with full TypeScript support and Svelte reactivity.

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

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

Usage Examples:

<script lang="ts">
  import { IconHome, IconHeart, IconArrowLeft } from '@tabler/icons-svelte';
  
  let iconSize = 24;
  let heartColor = 'red';
  let isActive = false;
</script>

<main>
  <!-- Basic usage -->
  <IconHome />
  
  <!-- With custom props -->
  <IconHeart 
    size={32} 
    color={heartColor}
    stroke={1.5}
    class="heart-icon"
  />
  
  <!-- With reactive props -->
  <IconArrowLeft 
    size={iconSize} 
    color={isActive ? 'blue' : 'gray'}
    on:click={() => history.back()}
  />
  
  <!-- With dynamic class -->
  <IconHome 
    class={isActive ? 'active' : 'inactive'}
    size={isActive ? 32 : 24}
  />
</main>

<style>
  .heart-icon {
    cursor: pointer;
    transition: transform 0.2s;
  }
  
  .heart-icon:hover {
    transform: scale(1.1);
  }
  
  .active {
    color: #3b82f6;
  }
  
  .inactive {
    color: #6b7280;
  }
</style>

Icon Component Props

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

interface IconProps {
  /** 
   * Icon size in pixels (applies to both width and height)
   * @default 24
   */
  size?: number;
  
  /** 
   * Icon stroke color (outline icons) or fill color (filled icons)
   * @default "currentColor"
   */
  color?: string;
  
  /** 
   * Stroke width for outline icons
   * @default 2
   */
  stroke?: number;
  
  /** 
   * CSS class name applied to the SVG element
   * Can be reactive
   */
  class?: string;
}

// Event handlers (available on all icon components)
interface IconEvents {
  /** Click event handler */
  on:click?: (event: MouseEvent) => void;
  /** Mouse enter event handler */
  on:mouseenter?: (event: MouseEvent) => void;
  /** Mouse leave event handler */
  on:mouseleave?: (event: MouseEvent) => void;
}

Usage Examples:

<script lang="ts">
  import { IconUser, IconSettings, IconHome } from '@tabler/icons-svelte';
  
  let dynamicSize = 24;
  let strokeWidth = 2;
  let themeColor = '#3b82f6';
  let isHovered = false;
  let isError = false;
  
  function handleClick() {
    console.log('Icon clicked');
  }
  
  function handleHover() {
    isHovered = true;
  }
  
  function handleLeave() {
    isHovered = false;
  }
</script>

<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 color="rgb(239, 68, 68)" />
  <IconSettings color={themeColor} />
  
  <!-- Stroke width variations -->
  <IconHome stroke={1} />   <!-- Thin -->
  <IconHome stroke={3} />   <!-- Thick -->
  <IconHome stroke={strokeWidth} /> <!-- Reactive -->
  
  <!-- CSS classes -->
  <IconSettings class="settings-icon rotating" />
  <IconSettings class={isHovered ? 'hovered' : ''} />
  
  <!-- Event handlers -->
  <IconSettings 
    on:click={handleClick}
    on:mouseenter={handleHover}
    on:mouseleave={handleLeave}
    class={isHovered ? 'hovered' : ''}
  />
  
  <!-- Conditional styling -->
  <IconSettings 
    color={isError ? 'red' : 'blue'}
    size={isError ? 32 : 24}
    class={isError ? 'error' : 'normal'}
  />
</div>

<style>
  .settings-icon {
    cursor: pointer;
    transition: transform 0.2s;
  }
  
  .rotating {
    animation: spin 2s linear infinite;
  }
  
  .hovered {
    transform: scale(1.1);
  }
  
  .error {
    filter: drop-shadow(0 0 4px red);
  }
  
  @keyframes spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
  }
</style>

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-svelte';

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

Usage Examples:

<script lang="ts">
  import { 
    IconHeart, 
    IconHeartFilled,
    IconStar,
    IconStarFilled,
    IconCheckCircle,
    IconCheckCircleFilled
  } from '@tabler/icons-svelte';
  
  let isFavorite = false;
  let rating = 0;
  let isCompleted = false;
  
  function toggleFavorite() {
    isFavorite = !isFavorite;
  }
  
  function setRating(value: number) {
    rating = value;
  }
</script>

<div>
  <!-- Toggle between outline and filled -->
  <button on:click={toggleFavorite}>
    {#if isFavorite}
      <IconHeartFilled color="red" />
    {:else}
      <IconHeart color="gray" />
    {/if}
    {isFavorite ? 'Favorited' : 'Favorite'}
  </button>
  
  <!-- Star rating component -->
  <div class="rating">
    {#each [1, 2, 3, 4, 5] as value}
      <button on:click={() => setRating(value)}>
        {#if value <= rating}
          <IconStarFilled color="gold" />
        {:else}
          <IconStar color="gray" />
        {/if}
      </button>
    {/each}
  </div>
  
  <!-- Conditional icon rendering -->
  {#if isCompleted}
    <IconCheckCircleFilled color="green" />
  {:else}
    <IconCheckCircle color="gray" />
  {/if}
</div>

<style>
  .rating {
    display: flex;
    gap: 0.25rem;
  }
  
  .rating button {
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.25rem;
    border-radius: 0.25rem;
    transition: background-color 0.2s;
  }
  
  .rating button:hover {
    background-color: #f3f4f6;
  }
</style>

Reactive Store Integration

Deep integration with Svelte stores for reactive icon properties and global state management.

/**
 * Svelte stores integration patterns
 * Icons work seamlessly with writable, readable, and derived stores
 */

import { writable, derived } from 'svelte/store';

// Theme store example
const theme = writable('light');
const iconColor = derived(theme, $theme => $theme === 'dark' ? '#ffffff' : '#000000');
const iconSize = derived(theme, $theme => $theme === 'dark' ? 28 : 24);

// Animation store example
const isAnimating = writable(false);
const rotation = writable(0);

Usage Examples:

<script lang="ts">
  import { writable, derived } from 'svelte/store';
  import { 
    IconSun, 
    IconMoon, 
    IconLoader,
    IconCheck,
    IconX,
    IconClock
  } from '@tabler/icons-svelte';
  
  // Theme store
  const isDark = writable(false);
  const iconColor = derived(isDark, $isDark => $isDark ? '#ffffff' : '#000000');
  const iconSize = derived(isDark, $isDark => $isDark ? 28 : 24);
  
  function toggleTheme() {
    isDark.update(dark => !dark);
  }
  
  // Loading state store
  const isLoading = writable(false);
  const rotation = writable(0);
  
  // Auto-rotate when loading
  $: if ($isLoading) {
    const interval = setInterval(() => {
      rotation.update(r => r + 90);
    }, 200);
    
    // Cleanup when not loading
    const unsubscribe = isLoading.subscribe(loading => {
      if (!loading) {
        clearInterval(interval);
        unsubscribe();
      }
    });
  }
  
  // Status store
  const status = writable('pending'); // 'success' | 'error' | 'pending'
  const statusIcon = derived(status, $status => {
    switch ($status) {
      case 'success': return IconCheck;
      case 'error': return IconX;
      default: return IconClock;
    }
  });
  const statusColor = derived(status, $status => {
    switch ($status) {
      case 'success': return 'green';
      case 'error': return 'red';
      default: return 'gray';
    }
  });
</script>

<div>
  <!-- Theme-aware icons -->
  <button on:click={toggleTheme}>
    {#if $isDark}
      <IconMoon color={$iconColor} size={$iconSize} />
    {:else}
      <IconSun color={$iconColor} size={$iconSize} />
    {/if}
    Toggle Theme
  </button>
  
  <!-- Animated loading icon -->
  <IconLoader 
    style="transform: rotate({$rotation}deg); transition: transform 0.5s ease"
    class={$isLoading ? 'spinning' : ''}
  />
  
  <!-- Status-based icons -->
  <svelte:component 
    this={$statusIcon} 
    color={$statusColor}
    size={24}
  />
</div>

<style>
  .spinning {
    animation: spin 1s linear infinite;
  }
  
  @keyframes spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
  }
</style>

Component Composition Patterns

Advanced patterns for composing icon components with other Svelte components and logic.

/**
 * Component composition patterns
 * Creating reusable icon-based components with slots and props
 */

// Icon button component interface
interface IconButtonProps {
  icon: any; // Svelte component
  variant?: 'primary' | 'secondary' | 'ghost';
  size?: 'sm' | 'md' | 'lg';
  disabled?: boolean;
}

// Icon with tooltip interface
interface IconTooltipProps {
  icon: any;
  tooltip: string;
  position?: 'top' | 'bottom' | 'left' | 'right';
}

Usage Examples:

<!-- IconButton.svelte -->
<script lang="ts">
  export let icon: any;
  export let variant: 'primary' | 'secondary' | 'ghost' = 'primary';
  export let size: 'sm' | 'md' | 'lg' = 'md';
  export let disabled = false;
  
  $: iconSize = size === 'sm' ? 16 : size === 'lg' ? 24 : 20;
  $: buttonClass = `btn btn-${variant} btn-${size}`;
</script>

<button 
  class={buttonClass}
  {disabled}
  on:click
>
  <svelte:component this={icon} size={iconSize} />
  <slot />
</button>

<style>
  .btn {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    border: none;
    border-radius: 0.25rem;
    cursor: pointer;
    transition: all 0.2s;
  }
  
  .btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
  
  .btn-primary {
    background-color: #3b82f6;
    color: white;
  }
  
  .btn-secondary {
    background-color: #6b7280;
    color: white;
  }
  
  .btn-ghost {
    background-color: transparent;
    color: currentColor;
  }
  
  .btn-sm {
    padding: 0.25rem 0.5rem;
    font-size: 0.875rem;
  }
  
  .btn-lg {
    padding: 0.75rem 1.5rem;
    font-size: 1.125rem;
  }
</style>

<!-- Usage of IconButton -->
<script lang="ts">
  import IconButton from './IconButton.svelte';
  import { IconTrash, IconEdit, IconPlus } from '@tabler/icons-svelte';
  
  function handleAdd() {
    console.log('Add clicked');
  }
  
  function handleEdit() {
    console.log('Edit clicked');
  }
  
  function handleDelete() {
    console.log('Delete clicked');
  }
</script>

<div class="actions">
  <IconButton icon={IconPlus} variant="primary" on:click={handleAdd}>
    Add Item
  </IconButton>
  
  <IconButton icon={IconEdit} variant="secondary" on:click={handleEdit}>
    Edit
  </IconButton>
  
  <IconButton icon={IconTrash} variant="ghost" on:click={handleDelete}>
    Delete
  </IconButton>
</div>

<style>
  .actions {
    display: flex;
    gap: 0.5rem;
  }
</style>

Dynamic Icon Loading

Load icons dynamically based on string identifiers with TypeScript safety and performance optimization.

<script lang="ts">
  import type { ComponentType } from 'svelte';
  
  // Icon registry for dynamic loading
  const iconRegistry: Record<string, () => Promise<{ default: ComponentType }>> = {
    home: () => import('@tabler/icons-svelte').then(mod => ({ default: mod.IconHome })),
    user: () => import('@tabler/icons-svelte').then(mod => ({ default: mod.IconUser })),
    settings: () => import('@tabler/icons-svelte').then(mod => ({ default: mod.IconSettings })),
  };
  
  export let iconName: string;
  export let size = 24;
  export let color = 'currentColor';
  
  let IconComponent: ComponentType | null = null;
  let loading = false;
  let error = false;
  
  $: loadIcon(iconName);
  
  async function loadIcon(name: string) {
    if (!iconRegistry[name]) {
      error = true;
      return;
    }
    
    loading = true;
    error = false;
    
    try {
      const module = await iconRegistry[name]();
      IconComponent = module.default;
    } catch (err) {
      error = true;
      console.warn(`Failed to load icon: ${name}`, err);
    } finally {
      loading = false;
    }
  }
</script>

{#if loading}
  <div class="icon-placeholder loading" style="width: {size}px; height: {size}px;" />
{:else if error}
  <div class="icon-placeholder error" style="width: {size}px; height: {size}px;" />
{:else if IconComponent}
  <svelte:component this={IconComponent} {size} {color} />
{/if}

<style>
  .icon-placeholder {
    display: inline-block;
    border-radius: 0.25rem;
    animation: pulse 1.5s ease-in-out infinite;
  }
  
  .loading {
    background-color: #e5e7eb;
  }
  
  .error {
    background-color: #fca5a5;
  }
  
  @keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
  }
</style>

Common Usage Patterns

Icon Animation Components

Create animated icon components using Svelte's built-in animation capabilities.

<script lang="ts">
  import { fade, scale, fly } from 'svelte/transition';
  import { IconCheck, IconX, IconLoader } from '@tabler/icons-svelte';
  
  export let status: 'loading' | 'success' | 'error' = 'loading';
  export let size = 24;
  
  $: icon = status === 'success' ? IconCheck : 
            status === 'error' ? IconX : 
            IconLoader;
  
  $: color = status === 'success' ? 'green' : 
             status === 'error' ? 'red' : 
             'gray';
</script>

<div class="status-icon">
  {#key status}
    <svelte:component 
      this={icon} 
      {size} 
      {color}
      class={status === 'loading' ? 'spinning' : ''}
      in:scale={{ duration: 300 }}
      out:fade={{ duration: 200 }}
    />
  {/key}
</div>

<style>
  .status-icon {
    display: inline-block;
  }
  
  .spinning {
    animation: spin 1s linear infinite;
  }
  
  @keyframes spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
  }
</style>

Icon Grid Component

Create icon grid interfaces for icon selection and display.

<script lang="ts">
  import * as TablerIcons from '@tabler/icons-svelte';
  
  export let selectedIcon: string | null = null;
  export let onSelect: (iconName: string) => void = () => {};
  
  // Get all available icons
  const iconEntries = Object.entries(TablerIcons).filter(([name]) => 
    name.startsWith('Icon') && !name.includes('Filled')
  );
  
  function handleIconClick(iconName: string) {
    selectedIcon = iconName;
    onSelect(iconName);
  }
</script>

<div class="icon-grid">
  {#each iconEntries as [iconName, IconComponent]}
    <button 
      class="icon-card"
      class:selected={selectedIcon === iconName}
      on:click={() => handleIconClick(iconName)}
    >
      <svelte:component this={IconComponent} size={32} />
      <span class="icon-name">{iconName.replace('Icon', '')}</span>
    </button>
  {/each}
</div>

<style>
  .icon-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 0.5rem;
    padding: 1rem;
  }
  
  .icon-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 1rem;
    background: white;
    border: 1px solid #e5e7eb;
    border-radius: 0.5rem;
    cursor: pointer;
    transition: all 0.2s;
  }
  
  .icon-card:hover {
    background-color: #f9fafb;
    transform: translateY(-2px);
    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
  }
  
  .icon-card.selected {
    border-color: #3b82f6;
    background-color: #eff6ff;
  }
  
  .icon-name {
    font-size: 0.875rem;
    text-align: center;
    color: #6b7280;
  }
</style>

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