or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdmetadata.mdreact-components.mdsvelte-components.mdsvg-data.mdsvg-files.mdvue-components.md

svelte-components.mddocs/

0

# Svelte Components

1

2

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.

3

4

## Package Information

5

6

- **Package Name**: @tabler/icons-svelte

7

- **Installation**: `npm install @tabler/icons-svelte`

8

- **Peer Dependencies**: Svelte >= 3 < 6 || >= 5.0.0-next.0

9

10

## Core Imports

11

12

```typescript

13

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

14

```

15

16

## Capabilities

17

18

### Icon Component Import

19

20

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

21

22

```typescript { .api }

23

/**

24

* Individual icon component imports

25

* Pattern: Icon{PascalCaseName} for outline icons

26

* Pattern: Icon{PascalCaseName}Filled for filled icons

27

*/

28

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

29

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

30

import { IconHeartFilled } from '@tabler/icons-svelte';

31

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

32

33

interface IconProps {

34

/** Icon size in pixels (applies to both width and height) */

35

size?: number;

36

/** Icon stroke color (outline icons) or fill color (filled icons) */

37

color?: string;

38

/** Stroke width for outline icons */

39

stroke?: number;

40

/** CSS class name */

41

class?: string;

42

}

43

```

44

45

**Usage Examples:**

46

47

```svelte

48

<script lang="ts">

49

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

50

51

let iconSize = 24;

52

let heartColor = 'red';

53

let isActive = false;

54

</script>

55

56

<main>

57

<!-- Basic usage -->

58

<IconHome />

59

60

<!-- With custom props -->

61

<IconHeart

62

size={32}

63

color={heartColor}

64

stroke={1.5}

65

class="heart-icon"

66

/>

67

68

<!-- With reactive props -->

69

<IconArrowLeft

70

size={iconSize}

71

color={isActive ? 'blue' : 'gray'}

72

on:click={() => history.back()}

73

/>

74

75

<!-- With dynamic class -->

76

<IconHome

77

class={isActive ? 'active' : 'inactive'}

78

size={isActive ? 32 : 24}

79

/>

80

</main>

81

82

<style>

83

.heart-icon {

84

cursor: pointer;

85

transition: transform 0.2s;

86

}

87

88

.heart-icon:hover {

89

transform: scale(1.1);

90

}

91

92

.active {

93

color: #3b82f6;

94

}

95

96

.inactive {

97

color: #6b7280;

98

}

99

</style>

100

```

101

102

### Icon Component Props

103

104

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

105

106

```typescript { .api }

107

interface IconProps {

108

/**

109

* Icon size in pixels (applies to both width and height)

110

* @default 24

111

*/

112

size?: number;

113

114

/**

115

* Icon stroke color (outline icons) or fill color (filled icons)

116

* @default "currentColor"

117

*/

118

color?: string;

119

120

/**

121

* Stroke width for outline icons

122

* @default 2

123

*/

124

stroke?: number;

125

126

/**

127

* CSS class name applied to the SVG element

128

* Can be reactive

129

*/

130

class?: string;

131

}

132

133

// Event handlers (available on all icon components)

134

interface IconEvents {

135

/** Click event handler */

136

on:click?: (event: MouseEvent) => void;

137

/** Mouse enter event handler */

138

on:mouseenter?: (event: MouseEvent) => void;

139

/** Mouse leave event handler */

140

on:mouseleave?: (event: MouseEvent) => void;

141

}

142

```

143

144

**Usage Examples:**

145

146

```svelte

147

<script lang="ts">

148

import { IconUser, IconSettings, IconHome } from '@tabler/icons-svelte';

149

150

let dynamicSize = 24;

151

let strokeWidth = 2;

152

let themeColor = '#3b82f6';

153

let isHovered = false;

154

let isError = false;

155

156

function handleClick() {

157

console.log('Icon clicked');

158

}

159

160

function handleHover() {

161

isHovered = true;

162

}

163

164

function handleLeave() {

165

isHovered = false;

166

}

167

</script>

168

169

<div>

170

<!-- Size variations -->

171

<IconUser size={16} /> <!-- Small -->

172

<IconUser size={24} /> <!-- Default -->

173

<IconUser size={32} /> <!-- Large -->

174

<IconUser size={dynamicSize} /> <!-- Reactive -->

175

176

<!-- Color variations -->

177

<IconSettings color="#3b82f6" />

178

<IconSettings color="rgb(239, 68, 68)" />

179

<IconSettings color={themeColor} />

180

181

<!-- Stroke width variations -->

182

<IconHome stroke={1} /> <!-- Thin -->

183

<IconHome stroke={3} /> <!-- Thick -->

184

<IconHome stroke={strokeWidth} /> <!-- Reactive -->

185

186

<!-- CSS classes -->

187

<IconSettings class="settings-icon rotating" />

188

<IconSettings class={isHovered ? 'hovered' : ''} />

189

190

<!-- Event handlers -->

191

<IconSettings

192

on:click={handleClick}

193

on:mouseenter={handleHover}

194

on:mouseleave={handleLeave}

195

class={isHovered ? 'hovered' : ''}

196

/>

197

198

<!-- Conditional styling -->

199

<IconSettings

200

color={isError ? 'red' : 'blue'}

201

size={isError ? 32 : 24}

202

class={isError ? 'error' : 'normal'}

203

/>

204

</div>

205

206

<style>

207

.settings-icon {

208

cursor: pointer;

209

transition: transform 0.2s;

210

}

211

212

.rotating {

213

animation: spin 2s linear infinite;

214

}

215

216

.hovered {

217

transform: scale(1.1);

218

}

219

220

.error {

221

filter: drop-shadow(0 0 4px red);

222

}

223

224

@keyframes spin {

225

from { transform: rotate(0deg); }

226

to { transform: rotate(360deg); }

227

}

228

</style>

229

```

230

231

### Outline vs Filled Variants

232

233

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

234

235

```typescript { .api }

236

/**

237

* Icon naming conventions:

238

* - Outline icons: Icon{PascalCaseName} (default style)

239

* - Filled icons: Icon{PascalCaseName}Filled

240

*

241

* Examples:

242

* - IconHome (outline) vs IconHomeFilled (filled)

243

* - IconHeart (outline) vs IconHeartFilled (filled)

244

* - IconStar (outline) vs IconStarFilled (filled)

245

*/

246

247

// Outline icons (4,964 available)

248

import {

249

IconHome,

250

IconHeart,

251

IconStar,

252

IconUser,

253

IconSettings

254

} from '@tabler/icons-svelte';

255

256

// Filled icons (981 available)

257

import {

258

IconHomeFilled,

259

IconHeartFilled,

260

IconStarFilled,

261

IconUserFilled,

262

IconSettingsFilled

263

} from '@tabler/icons-svelte';

264

```

265

266

**Usage Examples:**

267

268

```svelte

269

<script lang="ts">

270

import {

271

IconHeart,

272

IconHeartFilled,

273

IconStar,

274

IconStarFilled,

275

IconCheckCircle,

276

IconCheckCircleFilled

277

} from '@tabler/icons-svelte';

278

279

let isFavorite = false;

280

let rating = 0;

281

let isCompleted = false;

282

283

function toggleFavorite() {

284

isFavorite = !isFavorite;

285

}

286

287

function setRating(value: number) {

288

rating = value;

289

}

290

</script>

291

292

<div>

293

<!-- Toggle between outline and filled -->

294

<button on:click={toggleFavorite}>

295

{#if isFavorite}

296

<IconHeartFilled color="red" />

297

{:else}

298

<IconHeart color="gray" />

299

{/if}

300

{isFavorite ? 'Favorited' : 'Favorite'}

301

</button>

302

303

<!-- Star rating component -->

304

<div class="rating">

305

{#each [1, 2, 3, 4, 5] as value}

306

<button on:click={() => setRating(value)}>

307

{#if value <= rating}

308

<IconStarFilled color="gold" />

309

{:else}

310

<IconStar color="gray" />

311

{/if}

312

</button>

313

{/each}

314

</div>

315

316

<!-- Conditional icon rendering -->

317

{#if isCompleted}

318

<IconCheckCircleFilled color="green" />

319

{:else}

320

<IconCheckCircle color="gray" />

321

{/if}

322

</div>

323

324

<style>

325

.rating {

326

display: flex;

327

gap: 0.25rem;

328

}

329

330

.rating button {

331

background: none;

332

border: none;

333

cursor: pointer;

334

padding: 0.25rem;

335

border-radius: 0.25rem;

336

transition: background-color 0.2s;

337

}

338

339

.rating button:hover {

340

background-color: #f3f4f6;

341

}

342

</style>

343

```

344

345

### Reactive Store Integration

346

347

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

348

349

```typescript { .api }

350

/**

351

* Svelte stores integration patterns

352

* Icons work seamlessly with writable, readable, and derived stores

353

*/

354

355

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

356

357

// Theme store example

358

const theme = writable('light');

359

const iconColor = derived(theme, $theme => $theme === 'dark' ? '#ffffff' : '#000000');

360

const iconSize = derived(theme, $theme => $theme === 'dark' ? 28 : 24);

361

362

// Animation store example

363

const isAnimating = writable(false);

364

const rotation = writable(0);

365

```

366

367

**Usage Examples:**

368

369

```svelte

370

<script lang="ts">

371

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

372

import {

373

IconSun,

374

IconMoon,

375

IconLoader,

376

IconCheck,

377

IconX,

378

IconClock

379

} from '@tabler/icons-svelte';

380

381

// Theme store

382

const isDark = writable(false);

383

const iconColor = derived(isDark, $isDark => $isDark ? '#ffffff' : '#000000');

384

const iconSize = derived(isDark, $isDark => $isDark ? 28 : 24);

385

386

function toggleTheme() {

387

isDark.update(dark => !dark);

388

}

389

390

// Loading state store

391

const isLoading = writable(false);

392

const rotation = writable(0);

393

394

// Auto-rotate when loading

395

$: if ($isLoading) {

396

const interval = setInterval(() => {

397

rotation.update(r => r + 90);

398

}, 200);

399

400

// Cleanup when not loading

401

const unsubscribe = isLoading.subscribe(loading => {

402

if (!loading) {

403

clearInterval(interval);

404

unsubscribe();

405

}

406

});

407

}

408

409

// Status store

410

const status = writable('pending'); // 'success' | 'error' | 'pending'

411

const statusIcon = derived(status, $status => {

412

switch ($status) {

413

case 'success': return IconCheck;

414

case 'error': return IconX;

415

default: return IconClock;

416

}

417

});

418

const statusColor = derived(status, $status => {

419

switch ($status) {

420

case 'success': return 'green';

421

case 'error': return 'red';

422

default: return 'gray';

423

}

424

});

425

</script>

426

427

<div>

428

<!-- Theme-aware icons -->

429

<button on:click={toggleTheme}>

430

{#if $isDark}

431

<IconMoon color={$iconColor} size={$iconSize} />

432

{:else}

433

<IconSun color={$iconColor} size={$iconSize} />

434

{/if}

435

Toggle Theme

436

</button>

437

438

<!-- Animated loading icon -->

439

<IconLoader

440

style="transform: rotate({$rotation}deg); transition: transform 0.5s ease"

441

class={$isLoading ? 'spinning' : ''}

442

/>

443

444

<!-- Status-based icons -->

445

<svelte:component

446

this={$statusIcon}

447

color={$statusColor}

448

size={24}

449

/>

450

</div>

451

452

<style>

453

.spinning {

454

animation: spin 1s linear infinite;

455

}

456

457

@keyframes spin {

458

from { transform: rotate(0deg); }

459

to { transform: rotate(360deg); }

460

}

461

</style>

462

```

463

464

### Component Composition Patterns

465

466

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

467

468

```typescript { .api }

469

/**

470

* Component composition patterns

471

* Creating reusable icon-based components with slots and props

472

*/

473

474

// Icon button component interface

475

interface IconButtonProps {

476

icon: any; // Svelte component

477

variant?: 'primary' | 'secondary' | 'ghost';

478

size?: 'sm' | 'md' | 'lg';

479

disabled?: boolean;

480

}

481

482

// Icon with tooltip interface

483

interface IconTooltipProps {

484

icon: any;

485

tooltip: string;

486

position?: 'top' | 'bottom' | 'left' | 'right';

487

}

488

```

489

490

**Usage Examples:**

491

492

```svelte

493

<!-- IconButton.svelte -->

494

<script lang="ts">

495

export let icon: any;

496

export let variant: 'primary' | 'secondary' | 'ghost' = 'primary';

497

export let size: 'sm' | 'md' | 'lg' = 'md';

498

export let disabled = false;

499

500

$: iconSize = size === 'sm' ? 16 : size === 'lg' ? 24 : 20;

501

$: buttonClass = `btn btn-${variant} btn-${size}`;

502

</script>

503

504

<button

505

class={buttonClass}

506

{disabled}

507

on:click

508

>

509

<svelte:component this={icon} size={iconSize} />

510

<slot />

511

</button>

512

513

<style>

514

.btn {

515

display: flex;

516

align-items: center;

517

gap: 0.5rem;

518

padding: 0.5rem 1rem;

519

border: none;

520

border-radius: 0.25rem;

521

cursor: pointer;

522

transition: all 0.2s;

523

}

524

525

.btn:disabled {

526

opacity: 0.5;

527

cursor: not-allowed;

528

}

529

530

.btn-primary {

531

background-color: #3b82f6;

532

color: white;

533

}

534

535

.btn-secondary {

536

background-color: #6b7280;

537

color: white;

538

}

539

540

.btn-ghost {

541

background-color: transparent;

542

color: currentColor;

543

}

544

545

.btn-sm {

546

padding: 0.25rem 0.5rem;

547

font-size: 0.875rem;

548

}

549

550

.btn-lg {

551

padding: 0.75rem 1.5rem;

552

font-size: 1.125rem;

553

}

554

</style>

555

556

<!-- Usage of IconButton -->

557

<script lang="ts">

558

import IconButton from './IconButton.svelte';

559

import { IconTrash, IconEdit, IconPlus } from '@tabler/icons-svelte';

560

561

function handleAdd() {

562

console.log('Add clicked');

563

}

564

565

function handleEdit() {

566

console.log('Edit clicked');

567

}

568

569

function handleDelete() {

570

console.log('Delete clicked');

571

}

572

</script>

573

574

<div class="actions">

575

<IconButton icon={IconPlus} variant="primary" on:click={handleAdd}>

576

Add Item

577

</IconButton>

578

579

<IconButton icon={IconEdit} variant="secondary" on:click={handleEdit}>

580

Edit

581

</IconButton>

582

583

<IconButton icon={IconTrash} variant="ghost" on:click={handleDelete}>

584

Delete

585

</IconButton>

586

</div>

587

588

<style>

589

.actions {

590

display: flex;

591

gap: 0.5rem;

592

}

593

</style>

594

```

595

596

### Dynamic Icon Loading

597

598

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

599

600

```svelte

601

<script lang="ts">

602

import type { ComponentType } from 'svelte';

603

604

// Icon registry for dynamic loading

605

const iconRegistry: Record<string, () => Promise<{ default: ComponentType }>> = {

606

home: () => import('@tabler/icons-svelte').then(mod => ({ default: mod.IconHome })),

607

user: () => import('@tabler/icons-svelte').then(mod => ({ default: mod.IconUser })),

608

settings: () => import('@tabler/icons-svelte').then(mod => ({ default: mod.IconSettings })),

609

};

610

611

export let iconName: string;

612

export let size = 24;

613

export let color = 'currentColor';

614

615

let IconComponent: ComponentType | null = null;

616

let loading = false;

617

let error = false;

618

619

$: loadIcon(iconName);

620

621

async function loadIcon(name: string) {

622

if (!iconRegistry[name]) {

623

error = true;

624

return;

625

}

626

627

loading = true;

628

error = false;

629

630

try {

631

const module = await iconRegistry[name]();

632

IconComponent = module.default;

633

} catch (err) {

634

error = true;

635

console.warn(`Failed to load icon: ${name}`, err);

636

} finally {

637

loading = false;

638

}

639

}

640

</script>

641

642

{#if loading}

643

<div class="icon-placeholder loading" style="width: {size}px; height: {size}px;" />

644

{:else if error}

645

<div class="icon-placeholder error" style="width: {size}px; height: {size}px;" />

646

{:else if IconComponent}

647

<svelte:component this={IconComponent} {size} {color} />

648

{/if}

649

650

<style>

651

.icon-placeholder {

652

display: inline-block;

653

border-radius: 0.25rem;

654

animation: pulse 1.5s ease-in-out infinite;

655

}

656

657

.loading {

658

background-color: #e5e7eb;

659

}

660

661

.error {

662

background-color: #fca5a5;

663

}

664

665

@keyframes pulse {

666

0%, 100% { opacity: 1; }

667

50% { opacity: 0.5; }

668

}

669

</style>

670

```

671

672

## Common Usage Patterns

673

674

### Icon Animation Components

675

676

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

677

678

```svelte

679

<script lang="ts">

680

import { fade, scale, fly } from 'svelte/transition';

681

import { IconCheck, IconX, IconLoader } from '@tabler/icons-svelte';

682

683

export let status: 'loading' | 'success' | 'error' = 'loading';

684

export let size = 24;

685

686

$: icon = status === 'success' ? IconCheck :

687

status === 'error' ? IconX :

688

IconLoader;

689

690

$: color = status === 'success' ? 'green' :

691

status === 'error' ? 'red' :

692

'gray';

693

</script>

694

695

<div class="status-icon">

696

{#key status}

697

<svelte:component

698

this={icon}

699

{size}

700

{color}

701

class={status === 'loading' ? 'spinning' : ''}

702

in:scale={{ duration: 300 }}

703

out:fade={{ duration: 200 }}

704

/>

705

{/key}

706

</div>

707

708

<style>

709

.status-icon {

710

display: inline-block;

711

}

712

713

.spinning {

714

animation: spin 1s linear infinite;

715

}

716

717

@keyframes spin {

718

from { transform: rotate(0deg); }

719

to { transform: rotate(360deg); }

720

}

721

</style>

722

```

723

724

### Icon Grid Component

725

726

Create icon grid interfaces for icon selection and display.

727

728

```svelte

729

<script lang="ts">

730

import * as TablerIcons from '@tabler/icons-svelte';

731

732

export let selectedIcon: string | null = null;

733

export let onSelect: (iconName: string) => void = () => {};

734

735

// Get all available icons

736

const iconEntries = Object.entries(TablerIcons).filter(([name]) =>

737

name.startsWith('Icon') && !name.includes('Filled')

738

);

739

740

function handleIconClick(iconName: string) {

741

selectedIcon = iconName;

742

onSelect(iconName);

743

}

744

</script>

745

746

<div class="icon-grid">

747

{#each iconEntries as [iconName, IconComponent]}

748

<button

749

class="icon-card"

750

class:selected={selectedIcon === iconName}

751

on:click={() => handleIconClick(iconName)}

752

>

753

<svelte:component this={IconComponent} size={32} />

754

<span class="icon-name">{iconName.replace('Icon', '')}</span>

755

</button>

756

{/each}

757

</div>

758

759

<style>

760

.icon-grid {

761

display: grid;

762

grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));

763

gap: 0.5rem;

764

padding: 1rem;

765

}

766

767

.icon-card {

768

display: flex;

769

flex-direction: column;

770

align-items: center;

771

gap: 0.5rem;

772

padding: 1rem;

773

background: white;

774

border: 1px solid #e5e7eb;

775

border-radius: 0.5rem;

776

cursor: pointer;

777

transition: all 0.2s;

778

}

779

780

.icon-card:hover {

781

background-color: #f9fafb;

782

transform: translateY(-2px);

783

box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);

784

}

785

786

.icon-card.selected {

787

border-color: #3b82f6;

788

background-color: #eff6ff;

789

}

790

791

.icon-name {

792

font-size: 0.875rem;

793

text-align: center;

794

color: #6b7280;

795

}

796

</style>

797

```