Skip to content

Commit f59df58

Browse files
authored
Add /dev/icons to preview icons during development (#929)
1 parent 1cb4b01 commit f59df58

1 file changed

Lines changed: 141 additions & 0 deletions

File tree

src/routes/dev/icons/+page.svelte

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<!-- Icon Gallery for Development -->
2+
<script lang="ts">
3+
import { dev } from '$app/environment';
4+
import { goto } from '$app/navigation';
5+
import { onMount } from 'svelte';
6+
7+
// Redirect to home if not in development mode
8+
if (!dev) {
9+
goto('/');
10+
}
11+
12+
// Automatically import all icon components using Vite's import.meta.glob
13+
const iconModules = import.meta.glob('$lib/icons/**/*.svelte', { eager: true });
14+
15+
let icons: Array<{ name: string; path: string; component: any }> = [];
16+
let groupedIcons: { [folder: string]: Array<{ name: string; path: string; component: any }> } =
17+
{};
18+
19+
onMount(() => {
20+
// Process the imported modules
21+
icons = Object.entries(iconModules)
22+
.map(([path, module]) => {
23+
// Extract the icon name from the file path
24+
const pathParts = path.split('/');
25+
const fileName = pathParts[pathParts.length - 1];
26+
const name = fileName.replace('.svelte', '');
27+
28+
// Get relative path for display (remove the $lib/icons/ part)
29+
const relativePath = path.replace(/.*\/icons\//, '');
30+
31+
return {
32+
name,
33+
path: relativePath,
34+
component: (module as any).default
35+
};
36+
})
37+
.sort((a, b) => a.name.localeCompare(b.name));
38+
39+
// Group icons by folder
40+
groupedIcons = {};
41+
icons.forEach((icon) => {
42+
const folder = icon.path.includes('/') ? icon.path.split('/')[0] : 'Root Icons';
43+
if (!groupedIcons[folder]) {
44+
groupedIcons[folder] = [];
45+
}
46+
groupedIcons[folder].push(icon);
47+
});
48+
});
49+
50+
let selectedSize = '24';
51+
let selectedColor = '#000000';
52+
const sizes = ['16', '20', '24', '32', '48', '64'];
53+
const colors = ['#000000', '#ffffff', '#3b82f6', '#ef4444', '#10b981', '#f59e0b', '#8b5cf6'];
54+
</script>
55+
56+
<svelte:head>
57+
<title>Icon Gallery - Development</title>
58+
</svelte:head>
59+
60+
{#if dev}
61+
<div class="p-6 max-w-screen-lg mx-auto">
62+
<h1 class="text-3xl font-bold mb-6">SVG Icon Gallery</h1>
63+
64+
<div class="mb-6 flex gap-4 items-center flex-wrap">
65+
<div class="flex items-center gap-2">
66+
<label for="size-select" class="font-medium">Size:</label>
67+
<select id="size-select" bind:value={selectedSize} class="border rounded px-2 py-1">
68+
{#each sizes as size}
69+
<option value={size}>{size}px</option>
70+
{/each}
71+
</select>
72+
</div>
73+
74+
<div class="flex items-center gap-2">
75+
<label for="color-input" class="font-medium">Color:</label>
76+
<input
77+
id="color-input"
78+
type="color"
79+
bind:value={selectedColor}
80+
class="w-8 h-8 border rounded cursor-pointer"
81+
/>
82+
<span class="text-sm text-gray-600">{selectedColor}</span>
83+
</div>
84+
</div>
85+
86+
{#each Object.entries(groupedIcons) as [folder, folderIcons]}
87+
<div class="mb-8">
88+
<h2 class="text-xl font-semibold mb-4 pb-2 border-b border-gray-300">
89+
{folder}
90+
<span class="text-sm text-gray-500 font-normal ml-2"
91+
>({folderIcons.length} icons)</span
92+
>
93+
</h2>
94+
95+
<div class="grid grid-cols-2 md:grid-cols-4 gap-6">
96+
{#each folderIcons as icon}
97+
<div
98+
class="flex flex-col items-center p-4 border rounded-lg hover:bg-gray-50 transition-colors min-w-[250]"
99+
>
100+
<div
101+
class="flex items-center justify-center w-16 h-16 mb-2 bg-white border rounded"
102+
>
103+
<svelte:component
104+
this={icon.component}
105+
size={selectedSize}
106+
color={selectedColor}
107+
/>
108+
</div>
109+
<span class="text-sm text-center font-mono break-all">{icon.name}</span>
110+
<span class="text-xs text-gray-500 text-center mt-1">{icon.path}</span>
111+
</div>
112+
{/each}
113+
</div>
114+
</div>
115+
{/each}
116+
117+
<div class="mt-8 p-4 bg-gray-100 rounded-lg">
118+
<h3 class="font-bold mb-2">Usage Example:</h3>
119+
<pre class="text-sm bg-white p-2 rounded border"><code
120+
>&lt;PlayIcon size="{selectedSize}" color="{selectedColor}" /&gt;</code
121+
></pre>
122+
<div class="mt-2 text-sm text-gray-600">
123+
<strong>Total Icons:</strong>
124+
{icons.length}
125+
</div>
126+
</div>
127+
</div>
128+
{:else}
129+
<div class="flex items-center justify-center min-h-screen">
130+
<div class="text-center">
131+
<h1 class="text-2xl font-bold text-gray-600">Development Tool</h1>
132+
<p class="text-gray-500 mt-2">This page is only available in development mode.</p>
133+
</div>
134+
</div>
135+
{/if}
136+
137+
<style>
138+
:global(body) {
139+
background-color: #f9fafb;
140+
}
141+
</style>

0 commit comments

Comments
 (0)