Frosicon
kagitmiadam'ın kişisel ikon kütüphanesi. Bu kütüphane tamamen kişisel kullanım için tasarlanmıştır. Astro, React ve Vanilla HTML için tek paket. Tip güvenli, tree-shake'li, sade.
npm i @kagitmiadam/frosicon
✨ Neler Var
- 🎯 Astro-first —
.astrocomponent olarak doğrudan kullanım - ⚛️ React —
SVGPropsile tam TypeScript desteği - 🧩 Sprite —
<symbol>+<use>ile DOM tasarrufu - 🪶 Core (vanilla) — string olarak SVG, framework yok
- 🌗
currentColordesteği — CSS ile renklendir - 📦 Tree-shake'li — sadece kullandığın ikon bundle'a girer
- 🎨 Boyut & renk prop'ları — her component'te
sizevecolor
📐 Hedef Matrisi
Aynı ikon için dört farklı kullanım yolu — projene uygun olanı seç, hepsi aynı paket içinde:
| Hedef | Kullanım Şekli | Avantaj |
|---|---|---|
| Astro | import { X } from "@kagitmiadam/frosicon" |
Astro projeleri için varsayılan |
| React | import { X } from "@kagitmiadam/frosicon/react" |
React/Next/Vite |
| Sprite | import { Icon } from "@kagitmiadam/frosicon/sprite" |
Çok tekrar eden ikonlar için |
| Core | import { getSvg } from "@kagitmiadam/frosicon/core" |
Her yerde, framework'süz |
🚀 Kullanım
1. Astro (varsayılan import)
---
import { Facebook, Calendar } from "@kagitmiadam/frosicon"
---
<Facebook size={24} color="#FFFFFF" class="hidden lg:block" />
<Calendar size={32} class="text-white" aria-label="Takvim" />
Props:
| Prop | Tip | Varsayılan | Açıklama |
|---|---|---|---|
size |
number | string |
24 |
width & height |
color |
string |
'currentColor' |
SVG fill |
class |
string |
— | CSS class |
...rest |
HTMLAttributes<'svg'> |
— | aria-*, data-*, event handler'lar |
Alt klasördeki ikonlara da kısayoldan erişebilirsin:
import { Facebook } from "@kagitmiadam/frosicon/social-media"
2. React
import { Facebook, Calendar } from "@kagitmiadam/frosicon/react"
export function Header() {
return (
<>
<Facebook size={24} color="#fff" className="hidden lg:block" />
<Calendar size={32} className="text-white" aria-label="Takvim" />
</>
)
}
⚠️ React'te
classdeğilclassNamekullanılır (JSX kuralı).
Props: SVGProps<SVGSVGElement> + size, color.
Alt grup:
import { Facebook } from "@kagitmiadam/frosicon/react/social-media"
3. Sprite — DOM tasarrufu için
Aynı ikonu çok kez kullandığın sayfalar için (örn. uzun listeler). Sprite tüm ikonları bir kez DOM'a gömer; kullandığın yerler sadece referans tutar.
---
// src/layouts/Layout.astro — bir kez
import { IconSprite } from "@kagitmiadam/frosicon/sprite"
---
<html>
<body>
<IconSprite />
<slot />
</body>
</html>
---
// herhangi bir sayfa
import { Icon } from "@kagitmiadam/frosicon/sprite"
---
<Icon name="Facebook" size={24} color="#fff" class="hidden lg:block" />
<Icon name="Calendar" size={32} class="text-white" />
Props:
| Prop | Tip | Açıklama |
|---|---|---|
name |
IconName |
TS union — autocomplete'li |
size |
number | string |
Varsayılan 24 |
color |
string |
Varsayılan 'currentColor' |
class |
string |
CSS class |
4. Core — Vanilla HTML / SSR / herhangi bir framework
import { getSvg, getIconNames } from "@kagitmiadam/frosicon/core"
const svgString = getSvg("social-media/facebook 1", {
size: 24,
color: "#1877F2",
className: "icon icon-facebook",
})
document.querySelector("#slot")!.innerHTML = svgString
console.log(getIconNames()) // mevcut tüm ikonların adları
🌈 Gradient & Özel Background — IconGradient
Standart ikonlar tek renkli (path → fill). Gradient, conic, radial, animasyonlu arka plan veya hatta resim ile boyamak için CSS mask trick'ini kullanan IconGradient component'i var:
---
import { IconSprite, IconGradient } from "@kagitmiadam/frosicon/sprite"
---
<IconSprite />
<IconGradient name="Hand" size={64}
background="linear-gradient(135deg, #06b6d4, #a855f7)" />
<IconGradient name="Like" size={48}
background="conic-gradient(from 0deg, #f43f5e, #f59e0b, #10b981, #06b6d4, #a855f7, #f43f5e)" />
<IconGradient name="Star" size={64}
background="radial-gradient(circle, gold, orange)" />
Props:
| Prop | Tip | Varsayılan | Açıklama |
|---|---|---|---|
name |
IconName |
— | Sprite ikonu |
size |
number | string |
24 |
width & height |
background |
string |
'currentColor' |
Geçerli her CSS background değeri — gradient, image, var(), color |
class |
string |
— | Ek CSS class |
Nasıl çalışıyor? İkon SVG'si CSS
maskolarak uygulanır,backgroundise maskenin altından görünür. Sprite ile aynı veriyi paylaşır (ekstra HTTP yok),<symbol>içeriğinden runtime'da birdata:URL üretilir.
React / Vanilla için
IconGradient Astro component'i. React veya framework dışı için aynı tekniği kendin uygula — getIconDataUrl(name) helper'ı ile ikon SVG'sini data URL olarak al:
import { getIconDataUrl } from "@kagitmiadam/frosicon/sprite"
export function GradientIcon({ name, size = 24, background }) {
const url = getIconDataUrl(name)
return (
<span
role="img"
aria-label={name}
style={{
display: 'inline-block',
width: size, height: size,
background,
WebkitMask: `url(${url}) center/contain no-repeat`,
mask: `url(${url}) center/contain no-repeat`,
WebkitMaskMode: 'alpha', maskMode: 'alpha',
}}
/>
)
}
⚠️ Sınırlama: Mask yöntemi ikonun silüetini alır — multi-color path veya orijinal ikon detayları (stroke vs fill ayrımı) kaybolur. Bizim ikonlar zaten tek renk olduğu için bu bir kayıp değil.
🎨 Renklendirme — currentColor
Tüm component'ler varsayılan olarak fill="currentColor" kullanır. Yani parent CSS rengi ne ise ikon onu alır:
<div style="color: tomato">
<Facebook size={48} /> {/* Tomato olur */}
</div>
<div class="text-blue-500">
<Calendar size={32} /> {/* Tailwind blue-500 olur */}
</div>
color prop'unu açıkça verirsen onu kullanır:
<Facebook color="#1877F2" />
🎯 Hangi Hedefi Ne Zaman?
| Senaryo | Öneri |
|---|---|
| Astro projesi, az çeşit/az tekrar ikon | Named import (import { X } from "@kagitmiadam/frosicon") |
| Astro projesi, aynı ikon defalarca tekrarlanıyor (liste, grid) | Sprite (<Icon name="X" />) |
| React projesi | /react import |
| Server'da SVG string'i lazım | Core (getSvg(...)) |
| Email template, framework dışı | Core |
Hepsini aynı projede karıştırabilirsin — çakışma yok.
Inline vs Sprite — küçük performans rehberi
50 yerde aynı Facebook ikonunu kullandığını düşün:
| Inline (named import) | Sprite | |
|---|---|---|
| Path data DOM'da | 50 kez | 1 kez (symbol içinde) |
<svg> node |
50 | 50 + 1 sprite |
| Tree-shake | ✅ Sadece kullandığın ikon | ❌ Tüm ikonlar bir arada |
Pratik: 3-5 ikon farklı yerlerde → inline; 20+ ikon, çoğu birden fazla yerde → sprite.
🧹 IDE Auto-Import'u Hedefe Göre Kısıtla
Aynı paket Astro / React / Sprite / Core hedeflerini birlikte export ediyor. VS Code bütün hedefleri auto-import önerisinde gösterir — Astro projende Linkedin yazınca hem @kagitmiadam/frosicon hem @kagitmiadam/frosicon/react çıkar.
Sadece bir hedefi kullanıyorsan, projendeki .vscode/settings.json'a ekle:
Astro projesi (React ve Core önerilerini gizle):
{
"typescript.preferences.autoImportFileExcludePatterns": [
"**/@kagitmiadam/frosicon/dist/react/**",
"**/@kagitmiadam/frosicon/dist/core/**"
]
}
React projesi (Astro / Sprite / Core önerilerini gizle):
{
"typescript.preferences.autoImportFileExcludePatterns": [
"**/@kagitmiadam/frosicon/src/astro/**",
"**/@kagitmiadam/frosicon/src/sprite/**",
"**/@kagitmiadam/frosicon/dist/core/**"
]
}
Sadece o projeyi etkiler, paketi farklı hedeflerle kullanan diğer projeler etkilenmez. Manuel import yine de çalışır — sadece autocomplete listesi sadeleşir.
Alternatif: ESLint kullanıyorsan
no-restricted-importskuralıyla aynı sonucu alır + kuralı bozan import'u hata olarak gösterirsin.
🧪 TypeScript
Tüm hedeflerde tam tip desteği var:
// React
import type { ComponentProps } from "react"
import { Facebook } from "@kagitmiadam/frosicon/react"
type Props = ComponentProps<typeof Facebook>
// Sprite — IconName union
import type { IconName } from "@kagitmiadam/frosicon/sprite"
const myIcon: IconName = "Facebook" // ✓ autocomplete'li
📜 Lisans
MIT
Çay demle, kod yaz. ☕