@proveanything/smartlinks-utils-ui 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -371,6 +371,7 @@ var IconPickerContent = ({
371
371
  availableFamilies.length > 1 && /* @__PURE__ */ jsx("div", { className: "flex gap-1 border-b border-border pb-2", children: availableFamilies.map((f) => /* @__PURE__ */ jsx(
372
372
  "button",
373
373
  {
374
+ type: "button",
374
375
  onClick: () => setActiveFamily(f),
375
376
  className: cn(
376
377
  "px-3 py-1.5 text-xs font-semibold rounded-md transition-colors",
@@ -384,6 +385,7 @@ var IconPickerContent = ({
384
385
  /* @__PURE__ */ jsx(
385
386
  "button",
386
387
  {
388
+ type: "button",
387
389
  onClick: () => setActiveStyle(null),
388
390
  className: cn(
389
391
  "px-2.5 py-1 text-xs font-medium rounded-full transition-colors",
@@ -395,6 +397,7 @@ var IconPickerContent = ({
395
397
  availableStyles.map((s) => /* @__PURE__ */ jsx(
396
398
  "button",
397
399
  {
400
+ type: "button",
398
401
  onClick: () => setActiveStyle(s === activeStyle ? null : s),
399
402
  className: cn(
400
403
  "px-2.5 py-1 text-xs font-medium rounded-full capitalize transition-colors",
@@ -420,6 +423,7 @@ var IconPickerContent = ({
420
423
  return /* @__PURE__ */ jsx(
421
424
  "button",
422
425
  {
426
+ type: "button",
423
427
  onClick: () => handleSelect(icon.id),
424
428
  onMouseEnter: () => setHoveredId(icon.id),
425
429
  onMouseLeave: () => setHoveredId(null),
@@ -441,6 +445,7 @@ var IconPickerContent = ({
441
445
  /* @__PURE__ */ jsx(
442
446
  "button",
443
447
  {
448
+ type: "button",
444
449
  onClick: () => setPage(Math.max(0, page - 1)),
445
450
  disabled: page === 0,
446
451
  className: "p-1 rounded hover:bg-accent disabled:opacity-30 transition-colors",
@@ -455,6 +460,7 @@ var IconPickerContent = ({
455
460
  /* @__PURE__ */ jsx(
456
461
  "button",
457
462
  {
463
+ type: "button",
458
464
  onClick: () => setPage(Math.min(totalPages - 1, page + 1)),
459
465
  disabled: page >= totalPages - 1,
460
466
  className: "p-1 rounded hover:bg-accent disabled:opacity-30 transition-colors",
@@ -466,15 +472,28 @@ var IconPickerContent = ({
466
472
  };
467
473
  var PickerDialog = ({ open, onClose, children }) => {
468
474
  if (!open) return null;
475
+ const stopEvent = (e) => {
476
+ e.stopPropagation();
477
+ };
469
478
  return /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [
470
479
  /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/50 backdrop-blur-sm", onClick: onClose }),
471
- /* @__PURE__ */ jsxs("div", { className: "relative z-10 w-full max-w-xl max-h-[80vh] bg-background rounded-xl shadow-2xl border border-border flex flex-col overflow-hidden mx-4", children: [
472
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-border", children: [
473
- /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-foreground", children: "Select Icon" }),
474
- /* @__PURE__ */ jsx("button", { onClick: onClose, className: "p-1 rounded hover:bg-accent transition-colors", children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4 text-muted-foreground" }) })
475
- ] }),
476
- /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto p-4", children })
477
- ] })
480
+ /* @__PURE__ */ jsxs(
481
+ "div",
482
+ {
483
+ className: "relative z-10 w-full max-w-xl max-h-[80vh] bg-background rounded-xl shadow-2xl border border-border flex flex-col overflow-hidden mx-4",
484
+ onClick: stopEvent,
485
+ onMouseDown: stopEvent,
486
+ onPointerDown: stopEvent,
487
+ onTouchStart: stopEvent,
488
+ children: [
489
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-border", children: [
490
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-foreground", children: "Select Icon" }),
491
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: onClose, className: "p-1 rounded hover:bg-accent transition-colors", children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4 text-muted-foreground" }) })
492
+ ] }),
493
+ /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto p-4", children })
494
+ ]
495
+ }
496
+ )
478
497
  ] });
479
498
  };
480
499
  var IconPicker = (props) => {
@@ -514,5 +533,5 @@ var IconPicker = (props) => {
514
533
  };
515
534
 
516
535
  export { IconPicker, parseFaClass, toFaClass };
517
- //# sourceMappingURL=chunk-HLFNSOPD.js.map
518
- //# sourceMappingURL=chunk-HLFNSOPD.js.map
536
+ //# sourceMappingURL=chunk-S6KH3YV4.js.map
537
+ //# sourceMappingURL=chunk-S6KH3YV4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/IconPicker/icon-index.ts","../src/components/IconPicker/useIconSearch.ts","../src/components/IconPicker/IconPicker.tsx"],"names":["useRef","useState","useEffect","useCallback"],"mappings":"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","file":"chunk-S6KH3YV4.js","sourcesContent":["// =============================================================================\r\n// ICON PICKER — FA GraphQL API Client\r\n// =============================================================================\r\n// Search-only approach: uses FA's Algolia search for queries.\r\n// For browsing (no query), fetches letter-by-letter in background.\r\n// =============================================================================\r\n\r\nimport type { IconFamily, IconStyle } from './types';\r\n\r\nexport interface IconEntry {\r\n id: string;\r\n label: string;\r\n unicode: string;\r\n families: IconFamily[];\r\n styles: IconStyle[];\r\n isBrand: boolean;\r\n terms: string[];\r\n}\r\n\r\nconst FA_API = 'https://api.fontawesome.com';\r\nconst FA_VERSION = '7.x';\r\n\r\nconst SEARCH_QUERY = `\r\n query Search($version: String!, $query: String!, $first: Int) {\r\n search(version: $version, query: $query, first: $first) {\r\n id\r\n label\r\n unicode\r\n familyStylesByLicense {\r\n pro {\r\n family\r\n style\r\n }\r\n }\r\n }\r\n }\r\n`;\r\n\r\ninterface FamilyStyleEntry { family: string; style: string; }\r\ninterface RawIcon {\r\n id: string;\r\n label: string;\r\n unicode: string;\r\n familyStylesByLicense: { pro: FamilyStyleEntry[] };\r\n}\r\n\r\nfunction mapRawIcon(raw: RawIcon): IconEntry {\r\n const proStyles = raw.familyStylesByLicense?.pro || [];\r\n const families = new Set<IconFamily>();\r\n const styles = new Set<IconStyle>();\r\n let isBrand = false;\r\n\r\n for (const fs of proStyles) {\r\n // FA API returns brand icons as {family:\"classic\", style:\"brands\"}\r\n if (fs.style === 'brands' || fs.family === 'brands') {\r\n families.add('brands');\r\n isBrand = true;\r\n } else if (fs.family === 'classic' || fs.family === 'sharp') {\r\n families.add('classic');\r\n if (['solid', 'regular', 'light'].includes(fs.style)) styles.add(fs.style as IconStyle);\r\n } else if (fs.family === 'duotone') {\r\n families.add('duotone');\r\n if (['solid', 'regular', 'light'].includes(fs.style)) styles.add(fs.style as IconStyle);\r\n }\r\n }\r\n\r\n return {\r\n id: raw.id, label: raw.label || raw.id, unicode: raw.unicode || '',\r\n families: [...families], styles: [...styles], isBrand,\r\n terms: [raw.id, raw.label?.toLowerCase() || ''],\r\n };\r\n}\r\n\r\nasync function gqlRequest<T>(query: string, variables: Record<string, any>): Promise<T> {\r\n const res = await fetch(FA_API, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ query, variables }),\r\n });\r\n if (!res.ok) throw new Error(`FA API error: ${res.status}`);\r\n const json = await res.json();\r\n if (json.errors?.length) throw new Error(json.errors[0].message);\r\n return json.data;\r\n}\r\n\r\n/** Search icons using FA's Algolia-powered search */\r\nexport async function searchIcons(query: string, first = 200): Promise<IconEntry[]> {\r\n const data = await gqlRequest<{ search: RawIcon[] }>(SEARCH_QUERY, {\r\n version: FA_VERSION, query, first,\r\n });\r\n return (data.search || []).map(mapRawIcon);\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Background catalog builder — fetches letter-by-letter\r\n// ---------------------------------------------------------------------------\r\nlet _catalog: Map<string, IconEntry> = new Map();\r\nlet _catalogListeners: Set<() => void> = new Set();\r\nlet _catalogLoading = false;\r\nlet _catalogLoaded = false;\r\n\r\nexport function getCatalog(): IconEntry[] {\r\n return [..._catalog.values()].sort((a, b) => a.id.localeCompare(b.id));\r\n}\r\n\r\nexport function isCatalogLoaded(): boolean { return _catalogLoaded; }\r\nexport function isCatalogLoading(): boolean { return _catalogLoading; }\r\n\r\nexport function subscribeCatalog(fn: () => void): () => void {\r\n _catalogListeners.add(fn);\r\n return () => { _catalogListeners.delete(fn); };\r\n}\r\n\r\nfunction notifyListeners() {\r\n for (const fn of _catalogListeners) fn();\r\n}\r\n\r\nconst BROWSE_QUERIES = [\r\n 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',\r\n 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',\r\n '0', '1', '2', '3', '4', '5',\r\n];\r\n\r\nexport async function loadCatalogInBackground(): Promise<void> {\r\n if (_catalogLoaded || _catalogLoading) return;\r\n _catalogLoading = true;\r\n notifyListeners();\r\n\r\n // Fetch in batches of 3 to avoid hammering the API\r\n for (let i = 0; i < BROWSE_QUERIES.length; i += 3) {\r\n const batch = BROWSE_QUERIES.slice(i, i + 3);\r\n const results = await Promise.all(\r\n batch.map(q => searchIcons(q, 200).catch(() => [] as IconEntry[]))\r\n );\r\n for (const icons of results) {\r\n for (const icon of icons) {\r\n if (!_catalog.has(icon.id)) _catalog.set(icon.id, icon);\r\n }\r\n }\r\n notifyListeners();\r\n }\r\n\r\n _catalogLoaded = true;\r\n _catalogLoading = false;\r\n notifyListeners();\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Class helpers\r\n// ---------------------------------------------------------------------------\r\n\r\nexport function toFaClass(id: string, family: IconFamily, style: IconStyle | null): string {\r\n if (family === 'brands') return `fa-brands fa-${id}`;\r\n const stylePrefix = style ? `fa-${style}` : 'fa-solid';\r\n if (family === 'duotone') return `fa-duotone ${stylePrefix} fa-${id}`;\r\n return `${stylePrefix} fa-${id}`;\r\n}\r\n\r\nexport function parseFaClass(cls: string): { id: string; family: IconFamily; style: IconStyle | null } | null {\r\n if (!cls) return null;\r\n const parts = cls.trim().split(/\\s+/);\r\n if (parts.length < 2) return null;\r\n\r\n const hasDuotone = parts.includes('fa-duotone');\r\n const hasBrands = parts.includes('fa-brands');\r\n const prefixes = new Set(['fa-solid', 'fa-regular', 'fa-light', 'fa-thin', 'fa-brands', 'fa-duotone']);\r\n const namePart = parts.find(p => p.startsWith('fa-') && !prefixes.has(p));\r\n if (!namePart) return null;\r\n const id = namePart.replace(/^fa-/, '');\r\n\r\n if (hasBrands) return { id, family: 'brands', style: null };\r\n\r\n let style: IconStyle = 'solid';\r\n if (parts.includes('fa-regular')) style = 'regular';\r\n else if (parts.includes('fa-light')) style = 'light';\r\n\r\n return { id, family: hasDuotone ? 'duotone' : 'classic', style };\r\n}\r\n","// =============================================================================\r\n// ICON PICKER — Search Hook (FA GraphQL API, search-first)\r\n// =============================================================================\r\n\r\nimport { useState, useEffect, useMemo, useCallback, useRef } from 'react';\r\nimport type { IconEntry } from './icon-index';\r\nimport { searchIcons, loadCatalogInBackground, getCatalog, isCatalogLoaded, subscribeCatalog } from './icon-index';\r\nimport type { IconFamily, IconStyle } from './types';\r\n\r\nexport interface UseIconSearchOptions {\r\n families?: IconFamily[];\r\n styles?: IconStyle[];\r\n pageSize?: number;\r\n}\r\n\r\nexport function useIconSearch(options: UseIconSearchOptions = {}) {\r\n const { families, styles, pageSize = 100 } = options;\r\n\r\n const [catalog, setCatalog] = useState<IconEntry[]>(() => getCatalog());\r\n const [catalogReady, setCatalogReady] = useState(() => isCatalogLoaded());\r\n const [searchResults, setSearchResults] = useState<IconEntry[] | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [searching, setSearching] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [query, setQuery] = useState('');\r\n const [activeFamily, setActiveFamily] = useState<IconFamily>('classic');\r\n const [activeStyle, setActiveStyle] = useState<IconStyle | null>(null);\r\n const [page, setPage] = useState(0);\r\n const debounceRef = useRef<ReturnType<typeof setTimeout>>();\r\n\r\n // Subscribe to catalog updates\r\n useEffect(() => {\r\n const unsub = subscribeCatalog(() => {\r\n setCatalog(getCatalog());\r\n setCatalogReady(isCatalogLoaded());\r\n });\r\n return unsub;\r\n }, []);\r\n\r\n // Start background catalog load\r\n useEffect(() => {\r\n loadCatalogInBackground()\r\n .then(() => setLoading(false))\r\n .catch(err => { setError(err.message); setLoading(false); });\r\n }, []);\r\n\r\n // Mark not loading once we have some icons\r\n useEffect(() => {\r\n if (catalog.length > 0) setLoading(false);\r\n }, [catalog.length]);\r\n\r\n // Debounced search via GraphQL API\r\n const setSearch = useCallback((q: string) => {\r\n if (debounceRef.current) clearTimeout(debounceRef.current);\r\n debounceRef.current = setTimeout(async () => {\r\n setPage(0);\r\n const trimmed = q.trim();\r\n setQuery(trimmed);\r\n\r\n if (!trimmed) {\r\n setSearchResults(null);\r\n setSearching(false);\r\n return;\r\n }\r\n\r\n setSearching(true);\r\n try {\r\n const results = await searchIcons(trimmed, 300);\r\n setSearchResults(results);\r\n } catch {\r\n setSearchResults(null);\r\n } finally {\r\n setSearching(false);\r\n }\r\n }, 250);\r\n }, []);\r\n\r\n const source = searchResults ?? catalog;\r\n\r\n const availableFamilies = useMemo(() => {\r\n const set = new Set<IconFamily>();\r\n for (const icon of source) {\r\n for (const f of icon.families) {\r\n if (!families || families.includes(f)) set.add(f);\r\n }\r\n }\r\n const order: IconFamily[] = ['classic', 'duotone', 'brands'];\r\n return order.filter(f => set.has(f));\r\n }, [source, families]);\r\n\r\n // Auto-switch family if current one has no results (e.g. searching \"github\" → brands)\r\n useEffect(() => {\r\n if (availableFamilies.length > 0 && !availableFamilies.includes(activeFamily)) {\r\n setActiveFamily(availableFamilies[0]);\r\n }\r\n }, [availableFamilies, activeFamily]);\r\n\r\n const availableStyles = useMemo(() => {\r\n if (activeFamily === 'brands') return [];\r\n const set = new Set<IconStyle>();\r\n for (const icon of source) {\r\n if (!icon.families.includes(activeFamily)) continue;\r\n for (const s of icon.styles) {\r\n if (!styles || styles.includes(s)) set.add(s);\r\n }\r\n }\r\n const order: IconStyle[] = ['solid', 'regular', 'light'];\r\n return order.filter(s => set.has(s));\r\n }, [source, activeFamily, styles]);\r\n\r\n const handleSetFamily = useCallback((f: IconFamily) => {\r\n setActiveFamily(f);\r\n setActiveStyle(null);\r\n setPage(0);\r\n }, []);\r\n\r\n const filtered = useMemo(() => {\r\n let result = source;\r\n result = result.filter(icon => icon.families.includes(activeFamily));\r\n if (activeStyle && activeFamily !== 'brands') {\r\n result = result.filter(icon => icon.styles.includes(activeStyle));\r\n }\r\n if (query && !searchResults) {\r\n const lower = query.toLowerCase();\r\n const terms = lower.split(/\\s+/);\r\n result = result.filter(icon =>\r\n terms.every(term => icon.terms.some(t => t.includes(term)))\r\n );\r\n }\r\n return result;\r\n }, [source, searchResults, activeFamily, activeStyle, query]);\r\n\r\n const totalPages = Math.ceil(filtered.length / pageSize);\r\n const pageIcons = useMemo(\r\n () => filtered.slice(page * pageSize, (page + 1) * pageSize),\r\n [filtered, page, pageSize]\r\n );\r\n\r\n return {\r\n loading: loading && catalog.length === 0,\r\n searching,\r\n error,\r\n query,\r\n setSearch,\r\n activeFamily,\r\n setActiveFamily: handleSetFamily,\r\n availableFamilies,\r\n activeStyle,\r\n setActiveStyle: useCallback((s: IconStyle | null) => { setActiveStyle(s); setPage(0); }, []),\r\n availableStyles,\r\n filtered,\r\n pageIcons,\r\n page,\r\n setPage,\r\n totalPages,\r\n totalCount: filtered.length,\r\n catalogReady,\r\n };\r\n}\r\n","// =============================================================================\r\n// ICON PICKER — Component (FA7 two-level hierarchy)\r\n// =============================================================================\r\n// Family tabs (Classic/Duotone/Brands) → Style pills (Solid/Regular/Light)\r\n// =============================================================================\r\n\r\nimport React, { useState, useCallback, useRef, useEffect } from 'react';\r\nimport type { IconPickerProps, IconSelection, IconFamily, IconStyle } from './types';\r\nimport { useIconSearch } from './useIconSearch';\r\nimport { toFaClass, parseFaClass } from './icon-index';\r\nimport { cn } from '../../utils/cn';\r\nimport { Search, X, ChevronLeft, ChevronRight, Loader2, AlertCircle, Smile } from 'lucide-react';\r\n\r\n// ---------------------------------------------------------------------------\r\n// Family labels\r\n// ---------------------------------------------------------------------------\r\nconst FAMILY_LABELS: Record<IconFamily, string> = {\r\n classic: 'Classic',\r\n duotone: 'Duotone',\r\n brands: 'Brands',\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Icon Grid Content\r\n// ---------------------------------------------------------------------------\r\nconst IconPickerContent: React.FC<\r\n IconPickerProps & { onConfirm?: (icon: IconSelection) => void }\r\n> = ({\r\n value,\r\n onSelect,\r\n onConfirm,\r\n families: allowedFamilies,\r\n styles: allowedStyles,\r\n pageSize = 100,\r\n className,\r\n}) => {\r\n const {\r\n loading, searching, error, setSearch,\r\n activeFamily, setActiveFamily, availableFamilies,\r\n activeStyle, setActiveStyle, availableStyles,\r\n pageIcons, page, setPage, totalPages, totalCount,\r\n } = useIconSearch({ families: allowedFamilies, styles: allowedStyles, pageSize });\r\n\r\n const inputRef = useRef<HTMLInputElement>(null);\r\n const parsed = value ? parseFaClass(value) : null;\r\n const [hoveredId, setHoveredId] = useState<string | null>(null);\r\n\r\n useEffect(() => { inputRef.current?.focus(); }, [loading]);\r\n\r\n const handleSelect = useCallback((id: string) => {\r\n const family = activeFamily;\r\n const style: IconStyle | null = family === 'brands' ? null : (activeStyle || 'solid');\r\n const icon: IconSelection = {\r\n name: toFaClass(id, family, style),\r\n family,\r\n style,\r\n label: id,\r\n };\r\n onSelect?.(icon);\r\n onConfirm?.(icon);\r\n }, [onSelect, onConfirm, activeFamily, activeStyle]);\r\n\r\n if (loading) {\r\n return (\r\n <div className={cn('flex flex-col items-center justify-center py-12 gap-3', className)}>\r\n <Loader2 className=\"w-6 h-6 animate-spin text-muted-foreground\" />\r\n <p className=\"text-sm text-muted-foreground\">Loading icons…</p>\r\n </div>\r\n );\r\n }\r\n\r\n if (error) {\r\n return (\r\n <div className={cn('flex flex-col items-center justify-center py-12 gap-3', className)}>\r\n <AlertCircle className=\"w-6 h-6 text-destructive\" />\r\n <p className=\"text-sm text-destructive\">{error}</p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className={cn('space-y-3', className)}>\r\n {/* Search */}\r\n <div className=\"relative\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground\" />\r\n {searching && <Loader2 className=\"absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 animate-spin text-muted-foreground\" />}\r\n <input\r\n ref={inputRef}\r\n type=\"text\"\r\n placeholder=\"Search icons…\"\r\n onChange={(e) => setSearch(e.target.value)}\r\n className=\"w-full pl-9 pr-9 py-2 text-sm rounded-md border border-border bg-transparent focus:outline-none focus:ring-1 focus:ring-ring\"\r\n />\r\n </div>\r\n\r\n {/* Family tabs (primary) */}\r\n {availableFamilies.length > 1 && (\r\n <div className=\"flex gap-1 border-b border-border pb-2\">\r\n {availableFamilies.map((f) => (\r\n <button\r\n key={f}\r\n type=\"button\"\r\n onClick={() => setActiveFamily(f)}\r\n className={cn(\r\n 'px-3 py-1.5 text-xs font-semibold rounded-md transition-colors',\r\n f === activeFamily\r\n ? 'bg-primary text-primary-foreground'\r\n : 'text-muted-foreground hover:bg-accent hover:text-accent-foreground'\r\n )}\r\n >\r\n {FAMILY_LABELS[f]}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Style pills (secondary) — not shown for Brands */}\r\n {availableStyles.length > 1 && (\r\n <div className=\"flex gap-1 flex-wrap items-center\">\r\n <button\r\n type=\"button\"\r\n onClick={() => setActiveStyle(null)}\r\n className={cn(\r\n 'px-2.5 py-1 text-xs font-medium rounded-full transition-colors',\r\n !activeStyle\r\n ? 'bg-foreground text-background'\r\n : 'bg-muted text-muted-foreground hover:bg-accent'\r\n )}\r\n >\r\n All\r\n </button>\r\n {availableStyles.map((s) => (\r\n <button\r\n key={s}\r\n type=\"button\"\r\n onClick={() => setActiveStyle(s === activeStyle ? null : s)}\r\n className={cn(\r\n 'px-2.5 py-1 text-xs font-medium rounded-full capitalize transition-colors',\r\n s === activeStyle\r\n ? 'bg-foreground text-background'\r\n : 'bg-muted text-muted-foreground hover:bg-accent'\r\n )}\r\n >\r\n {s}\r\n </button>\r\n ))}\r\n <span className=\"ml-auto text-[11px] text-muted-foreground\">\r\n {totalCount} icons\r\n </span>\r\n </div>\r\n )}\r\n\r\n {/* Grid */}\r\n {pageIcons.length === 0 ? (\r\n <div className=\"flex flex-col items-center justify-center py-10 gap-2\">\r\n <Smile className=\"w-6 h-6 text-muted-foreground/40\" />\r\n <p className=\"text-sm text-muted-foreground\">No icons found</p>\r\n </div>\r\n ) : (\r\n <div className=\"grid grid-cols-8 sm:grid-cols-10 md:grid-cols-12 gap-1\">\r\n {pageIcons.map((icon) => {\r\n const isSelected = parsed?.id === icon.id && parsed?.family === activeFamily;\r\n const isHovered = hoveredId === icon.id;\r\n const displayStyle: IconStyle | null = activeFamily === 'brands' ? null : (activeStyle || 'solid');\r\n const cssClass = toFaClass(icon.id, activeFamily, displayStyle);\r\n\r\n return (\r\n <button\r\n key={icon.id}\r\n type=\"button\"\r\n onClick={() => handleSelect(icon.id)}\r\n onMouseEnter={() => setHoveredId(icon.id)}\r\n onMouseLeave={() => setHoveredId(null)}\r\n title={icon.label}\r\n className={cn(\r\n 'aspect-square flex items-center justify-center rounded-md text-base transition-all',\r\n isSelected\r\n ? 'bg-primary/10 text-primary ring-2 ring-primary'\r\n : isHovered\r\n ? 'bg-accent text-accent-foreground scale-110'\r\n : 'text-muted-foreground hover:bg-accent/50'\r\n )}\r\n >\r\n <i className={cssClass} />\r\n </button>\r\n );\r\n })}\r\n </div>\r\n )}\r\n\r\n {/* Hover preview — fixed height to prevent layout shift */}\r\n <div className=\"h-6 text-center\">\r\n {hoveredId && (\r\n <code className=\"text-[11px] text-muted-foreground bg-muted px-2 py-0.5 rounded\">\r\n fa-{hoveredId}\r\n </code>\r\n )}\r\n </div>\r\n\r\n {/* Pagination */}\r\n {totalPages > 1 && (\r\n <div className=\"flex items-center justify-center gap-2\">\r\n <button\r\n type=\"button\"\r\n onClick={() => setPage(Math.max(0, page - 1))}\r\n disabled={page === 0}\r\n className=\"p-1 rounded hover:bg-accent disabled:opacity-30 transition-colors\"\r\n >\r\n <ChevronLeft className=\"w-4 h-4\" />\r\n </button>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {page + 1} / {totalPages}\r\n </span>\r\n <button\r\n type=\"button\"\r\n onClick={() => setPage(Math.min(totalPages - 1, page + 1))}\r\n disabled={page >= totalPages - 1}\r\n className=\"p-1 rounded hover:bg-accent disabled:opacity-30 transition-colors\"\r\n >\r\n <ChevronRight className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Dialog wrapper\r\n// ---------------------------------------------------------------------------\r\nconst PickerDialog: React.FC<{\r\n open: boolean;\r\n onClose: () => void;\r\n children: React.ReactNode;\r\n}> = ({ open, onClose, children }) => {\r\n if (!open) return null;\r\n\r\n const stopEvent = (e: React.SyntheticEvent) => {\r\n e.stopPropagation();\r\n };\r\n\r\n return (\r\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\r\n <div className=\"absolute inset-0 bg-black/50 backdrop-blur-sm\" onClick={onClose} />\r\n <div\r\n className=\"relative z-10 w-full max-w-xl max-h-[80vh] bg-background rounded-xl shadow-2xl border border-border flex flex-col overflow-hidden mx-4\"\r\n onClick={stopEvent}\r\n onMouseDown={stopEvent}\r\n onPointerDown={stopEvent}\r\n onTouchStart={stopEvent}\r\n >\r\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border\">\r\n <h3 className=\"text-sm font-semibold text-foreground\">Select Icon</h3>\r\n <button type=\"button\" onClick={onClose} className=\"p-1 rounded hover:bg-accent transition-colors\">\r\n <X className=\"w-4 h-4 text-muted-foreground\" />\r\n </button>\r\n </div>\r\n <div className=\"flex-1 overflow-y-auto p-4\">{children}</div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Public API\r\n// ---------------------------------------------------------------------------\r\nexport const IconPicker: React.FC<IconPickerProps> = (props) => {\r\n const { mode = 'inline', trigger, open: controlledOpen, onClose, value, onSelect, className, ...rest } = props;\r\n\r\n const [internalOpen, setInternalOpen] = useState(false);\r\n const isOpen = controlledOpen ?? internalOpen;\r\n\r\n const handleClose = useCallback(() => {\r\n setInternalOpen(false);\r\n onClose?.();\r\n }, [onClose]);\r\n\r\n const handleSelectAndClose = useCallback((icon: IconSelection) => {\r\n onSelect?.(icon);\r\n handleClose();\r\n }, [onSelect, handleClose]);\r\n\r\n // Inline mode\r\n if (mode === 'inline') {\r\n return <IconPickerContent value={value} onSelect={onSelect} className={className} {...rest} />;\r\n }\r\n\r\n // Dialog mode\r\n const parsed = value ? parseFaClass(value) : null;\r\n const triggerElement = trigger || (\r\n <div className={cn(\r\n 'inline-flex items-center gap-2 px-3 py-2 rounded-md border border-border cursor-pointer',\r\n 'hover:border-ring transition-colors',\r\n className,\r\n )}>\r\n {parsed ? (\r\n <>\r\n <i className={value!} />\r\n <span className=\"text-sm text-muted-foreground\">fa-{parsed.id}</span>\r\n </>\r\n ) : (\r\n <span className=\"text-sm text-muted-foreground\">Choose icon…</span>\r\n )}\r\n <ChevronRight className=\"w-3.5 h-3.5 text-muted-foreground ml-auto\" />\r\n </div>\r\n );\r\n\r\n return (\r\n <>\r\n <span onClick={() => setInternalOpen(true)} className=\"cursor-pointer\">{triggerElement}</span>\r\n <PickerDialog open={isOpen} onClose={handleClose}>\r\n <IconPickerContent value={value} onSelect={handleSelectAndClose} {...rest} />\r\n </PickerDialog>\r\n </>\r\n );\r\n};\r\n"]}
@@ -1,4 +1,4 @@
1
- export { IconPicker, parseFaClass, toFaClass } from '../../chunk-HLFNSOPD.js';
1
+ export { IconPicker, parseFaClass, toFaClass } from '../../chunk-S6KH3YV4.js';
2
2
  import '../../chunk-L7FQ52F5.js';
3
3
  //# sourceMappingURL=index.js.map
4
4
  //# sourceMappingURL=index.js.map
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export { ASSET_MIME_FILTERS, AssetPicker, useAssets } from './chunk-WOCLZGRB.js';
2
2
  export { ConditionsEditor } from './chunk-IVUFK6SS.js';
3
- export { IconPicker } from './chunk-HLFNSOPD.js';
3
+ export { IconPicker } from './chunk-S6KH3YV4.js';
4
4
  export { CATEGORY_FALLBACKS, CATEGORY_LABELS, FontPicker, GOOGLE_FONTS_CATALOG, getGoogleFontUrl } from './chunk-4Z46C4MJ.js';
5
5
  export { cn } from './chunk-L7FQ52F5.js';
6
6
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks-utils-ui",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Reusable React components for SmartLinks microapps — Asset Picker, Conditions Editor, Icon Picker, and more.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/IconPicker/icon-index.ts","../src/components/IconPicker/useIconSearch.ts","../src/components/IconPicker/IconPicker.tsx"],"names":["useRef","useState","useEffect","useCallback"],"mappings":"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","file":"chunk-HLFNSOPD.js","sourcesContent":["// =============================================================================\r\n// ICON PICKER — FA GraphQL API Client\r\n// =============================================================================\r\n// Search-only approach: uses FA's Algolia search for queries.\r\n// For browsing (no query), fetches letter-by-letter in background.\r\n// =============================================================================\r\n\r\nimport type { IconFamily, IconStyle } from './types';\r\n\r\nexport interface IconEntry {\r\n id: string;\r\n label: string;\r\n unicode: string;\r\n families: IconFamily[];\r\n styles: IconStyle[];\r\n isBrand: boolean;\r\n terms: string[];\r\n}\r\n\r\nconst FA_API = 'https://api.fontawesome.com';\r\nconst FA_VERSION = '7.x';\r\n\r\nconst SEARCH_QUERY = `\r\n query Search($version: String!, $query: String!, $first: Int) {\r\n search(version: $version, query: $query, first: $first) {\r\n id\r\n label\r\n unicode\r\n familyStylesByLicense {\r\n pro {\r\n family\r\n style\r\n }\r\n }\r\n }\r\n }\r\n`;\r\n\r\ninterface FamilyStyleEntry { family: string; style: string; }\r\ninterface RawIcon {\r\n id: string;\r\n label: string;\r\n unicode: string;\r\n familyStylesByLicense: { pro: FamilyStyleEntry[] };\r\n}\r\n\r\nfunction mapRawIcon(raw: RawIcon): IconEntry {\r\n const proStyles = raw.familyStylesByLicense?.pro || [];\r\n const families = new Set<IconFamily>();\r\n const styles = new Set<IconStyle>();\r\n let isBrand = false;\r\n\r\n for (const fs of proStyles) {\r\n // FA API returns brand icons as {family:\"classic\", style:\"brands\"}\r\n if (fs.style === 'brands' || fs.family === 'brands') {\r\n families.add('brands');\r\n isBrand = true;\r\n } else if (fs.family === 'classic' || fs.family === 'sharp') {\r\n families.add('classic');\r\n if (['solid', 'regular', 'light'].includes(fs.style)) styles.add(fs.style as IconStyle);\r\n } else if (fs.family === 'duotone') {\r\n families.add('duotone');\r\n if (['solid', 'regular', 'light'].includes(fs.style)) styles.add(fs.style as IconStyle);\r\n }\r\n }\r\n\r\n return {\r\n id: raw.id, label: raw.label || raw.id, unicode: raw.unicode || '',\r\n families: [...families], styles: [...styles], isBrand,\r\n terms: [raw.id, raw.label?.toLowerCase() || ''],\r\n };\r\n}\r\n\r\nasync function gqlRequest<T>(query: string, variables: Record<string, any>): Promise<T> {\r\n const res = await fetch(FA_API, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ query, variables }),\r\n });\r\n if (!res.ok) throw new Error(`FA API error: ${res.status}`);\r\n const json = await res.json();\r\n if (json.errors?.length) throw new Error(json.errors[0].message);\r\n return json.data;\r\n}\r\n\r\n/** Search icons using FA's Algolia-powered search */\r\nexport async function searchIcons(query: string, first = 200): Promise<IconEntry[]> {\r\n const data = await gqlRequest<{ search: RawIcon[] }>(SEARCH_QUERY, {\r\n version: FA_VERSION, query, first,\r\n });\r\n return (data.search || []).map(mapRawIcon);\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Background catalog builder — fetches letter-by-letter\r\n// ---------------------------------------------------------------------------\r\nlet _catalog: Map<string, IconEntry> = new Map();\r\nlet _catalogListeners: Set<() => void> = new Set();\r\nlet _catalogLoading = false;\r\nlet _catalogLoaded = false;\r\n\r\nexport function getCatalog(): IconEntry[] {\r\n return [..._catalog.values()].sort((a, b) => a.id.localeCompare(b.id));\r\n}\r\n\r\nexport function isCatalogLoaded(): boolean { return _catalogLoaded; }\r\nexport function isCatalogLoading(): boolean { return _catalogLoading; }\r\n\r\nexport function subscribeCatalog(fn: () => void): () => void {\r\n _catalogListeners.add(fn);\r\n return () => { _catalogListeners.delete(fn); };\r\n}\r\n\r\nfunction notifyListeners() {\r\n for (const fn of _catalogListeners) fn();\r\n}\r\n\r\nconst BROWSE_QUERIES = [\r\n 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',\r\n 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',\r\n '0', '1', '2', '3', '4', '5',\r\n];\r\n\r\nexport async function loadCatalogInBackground(): Promise<void> {\r\n if (_catalogLoaded || _catalogLoading) return;\r\n _catalogLoading = true;\r\n notifyListeners();\r\n\r\n // Fetch in batches of 3 to avoid hammering the API\r\n for (let i = 0; i < BROWSE_QUERIES.length; i += 3) {\r\n const batch = BROWSE_QUERIES.slice(i, i + 3);\r\n const results = await Promise.all(\r\n batch.map(q => searchIcons(q, 200).catch(() => [] as IconEntry[]))\r\n );\r\n for (const icons of results) {\r\n for (const icon of icons) {\r\n if (!_catalog.has(icon.id)) _catalog.set(icon.id, icon);\r\n }\r\n }\r\n notifyListeners();\r\n }\r\n\r\n _catalogLoaded = true;\r\n _catalogLoading = false;\r\n notifyListeners();\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Class helpers\r\n// ---------------------------------------------------------------------------\r\n\r\nexport function toFaClass(id: string, family: IconFamily, style: IconStyle | null): string {\r\n if (family === 'brands') return `fa-brands fa-${id}`;\r\n const stylePrefix = style ? `fa-${style}` : 'fa-solid';\r\n if (family === 'duotone') return `fa-duotone ${stylePrefix} fa-${id}`;\r\n return `${stylePrefix} fa-${id}`;\r\n}\r\n\r\nexport function parseFaClass(cls: string): { id: string; family: IconFamily; style: IconStyle | null } | null {\r\n if (!cls) return null;\r\n const parts = cls.trim().split(/\\s+/);\r\n if (parts.length < 2) return null;\r\n\r\n const hasDuotone = parts.includes('fa-duotone');\r\n const hasBrands = parts.includes('fa-brands');\r\n const prefixes = new Set(['fa-solid', 'fa-regular', 'fa-light', 'fa-thin', 'fa-brands', 'fa-duotone']);\r\n const namePart = parts.find(p => p.startsWith('fa-') && !prefixes.has(p));\r\n if (!namePart) return null;\r\n const id = namePart.replace(/^fa-/, '');\r\n\r\n if (hasBrands) return { id, family: 'brands', style: null };\r\n\r\n let style: IconStyle = 'solid';\r\n if (parts.includes('fa-regular')) style = 'regular';\r\n else if (parts.includes('fa-light')) style = 'light';\r\n\r\n return { id, family: hasDuotone ? 'duotone' : 'classic', style };\r\n}\r\n","// =============================================================================\r\n// ICON PICKER — Search Hook (FA GraphQL API, search-first)\r\n// =============================================================================\r\n\r\nimport { useState, useEffect, useMemo, useCallback, useRef } from 'react';\r\nimport type { IconEntry } from './icon-index';\r\nimport { searchIcons, loadCatalogInBackground, getCatalog, isCatalogLoaded, subscribeCatalog } from './icon-index';\r\nimport type { IconFamily, IconStyle } from './types';\r\n\r\nexport interface UseIconSearchOptions {\r\n families?: IconFamily[];\r\n styles?: IconStyle[];\r\n pageSize?: number;\r\n}\r\n\r\nexport function useIconSearch(options: UseIconSearchOptions = {}) {\r\n const { families, styles, pageSize = 100 } = options;\r\n\r\n const [catalog, setCatalog] = useState<IconEntry[]>(() => getCatalog());\r\n const [catalogReady, setCatalogReady] = useState(() => isCatalogLoaded());\r\n const [searchResults, setSearchResults] = useState<IconEntry[] | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [searching, setSearching] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [query, setQuery] = useState('');\r\n const [activeFamily, setActiveFamily] = useState<IconFamily>('classic');\r\n const [activeStyle, setActiveStyle] = useState<IconStyle | null>(null);\r\n const [page, setPage] = useState(0);\r\n const debounceRef = useRef<ReturnType<typeof setTimeout>>();\r\n\r\n // Subscribe to catalog updates\r\n useEffect(() => {\r\n const unsub = subscribeCatalog(() => {\r\n setCatalog(getCatalog());\r\n setCatalogReady(isCatalogLoaded());\r\n });\r\n return unsub;\r\n }, []);\r\n\r\n // Start background catalog load\r\n useEffect(() => {\r\n loadCatalogInBackground()\r\n .then(() => setLoading(false))\r\n .catch(err => { setError(err.message); setLoading(false); });\r\n }, []);\r\n\r\n // Mark not loading once we have some icons\r\n useEffect(() => {\r\n if (catalog.length > 0) setLoading(false);\r\n }, [catalog.length]);\r\n\r\n // Debounced search via GraphQL API\r\n const setSearch = useCallback((q: string) => {\r\n if (debounceRef.current) clearTimeout(debounceRef.current);\r\n debounceRef.current = setTimeout(async () => {\r\n setPage(0);\r\n const trimmed = q.trim();\r\n setQuery(trimmed);\r\n\r\n if (!trimmed) {\r\n setSearchResults(null);\r\n setSearching(false);\r\n return;\r\n }\r\n\r\n setSearching(true);\r\n try {\r\n const results = await searchIcons(trimmed, 300);\r\n setSearchResults(results);\r\n } catch {\r\n setSearchResults(null);\r\n } finally {\r\n setSearching(false);\r\n }\r\n }, 250);\r\n }, []);\r\n\r\n const source = searchResults ?? catalog;\r\n\r\n const availableFamilies = useMemo(() => {\r\n const set = new Set<IconFamily>();\r\n for (const icon of source) {\r\n for (const f of icon.families) {\r\n if (!families || families.includes(f)) set.add(f);\r\n }\r\n }\r\n const order: IconFamily[] = ['classic', 'duotone', 'brands'];\r\n return order.filter(f => set.has(f));\r\n }, [source, families]);\r\n\r\n // Auto-switch family if current one has no results (e.g. searching \"github\" → brands)\r\n useEffect(() => {\r\n if (availableFamilies.length > 0 && !availableFamilies.includes(activeFamily)) {\r\n setActiveFamily(availableFamilies[0]);\r\n }\r\n }, [availableFamilies, activeFamily]);\r\n\r\n const availableStyles = useMemo(() => {\r\n if (activeFamily === 'brands') return [];\r\n const set = new Set<IconStyle>();\r\n for (const icon of source) {\r\n if (!icon.families.includes(activeFamily)) continue;\r\n for (const s of icon.styles) {\r\n if (!styles || styles.includes(s)) set.add(s);\r\n }\r\n }\r\n const order: IconStyle[] = ['solid', 'regular', 'light'];\r\n return order.filter(s => set.has(s));\r\n }, [source, activeFamily, styles]);\r\n\r\n const handleSetFamily = useCallback((f: IconFamily) => {\r\n setActiveFamily(f);\r\n setActiveStyle(null);\r\n setPage(0);\r\n }, []);\r\n\r\n const filtered = useMemo(() => {\r\n let result = source;\r\n result = result.filter(icon => icon.families.includes(activeFamily));\r\n if (activeStyle && activeFamily !== 'brands') {\r\n result = result.filter(icon => icon.styles.includes(activeStyle));\r\n }\r\n if (query && !searchResults) {\r\n const lower = query.toLowerCase();\r\n const terms = lower.split(/\\s+/);\r\n result = result.filter(icon =>\r\n terms.every(term => icon.terms.some(t => t.includes(term)))\r\n );\r\n }\r\n return result;\r\n }, [source, searchResults, activeFamily, activeStyle, query]);\r\n\r\n const totalPages = Math.ceil(filtered.length / pageSize);\r\n const pageIcons = useMemo(\r\n () => filtered.slice(page * pageSize, (page + 1) * pageSize),\r\n [filtered, page, pageSize]\r\n );\r\n\r\n return {\r\n loading: loading && catalog.length === 0,\r\n searching,\r\n error,\r\n query,\r\n setSearch,\r\n activeFamily,\r\n setActiveFamily: handleSetFamily,\r\n availableFamilies,\r\n activeStyle,\r\n setActiveStyle: useCallback((s: IconStyle | null) => { setActiveStyle(s); setPage(0); }, []),\r\n availableStyles,\r\n filtered,\r\n pageIcons,\r\n page,\r\n setPage,\r\n totalPages,\r\n totalCount: filtered.length,\r\n catalogReady,\r\n };\r\n}\r\n","// =============================================================================\r\n// ICON PICKER — Component (FA7 two-level hierarchy)\r\n// =============================================================================\r\n// Family tabs (Classic/Duotone/Brands) → Style pills (Solid/Regular/Light)\r\n// =============================================================================\r\n\r\nimport React, { useState, useCallback, useRef, useEffect } from 'react';\r\nimport type { IconPickerProps, IconSelection, IconFamily, IconStyle } from './types';\r\nimport { useIconSearch } from './useIconSearch';\r\nimport { toFaClass, parseFaClass } from './icon-index';\r\nimport { cn } from '../../utils/cn';\r\nimport { Search, X, ChevronLeft, ChevronRight, Loader2, AlertCircle, Smile } from 'lucide-react';\r\n\r\n// ---------------------------------------------------------------------------\r\n// Family labels\r\n// ---------------------------------------------------------------------------\r\nconst FAMILY_LABELS: Record<IconFamily, string> = {\r\n classic: 'Classic',\r\n duotone: 'Duotone',\r\n brands: 'Brands',\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Icon Grid Content\r\n// ---------------------------------------------------------------------------\r\nconst IconPickerContent: React.FC<\r\n IconPickerProps & { onConfirm?: (icon: IconSelection) => void }\r\n> = ({\r\n value,\r\n onSelect,\r\n onConfirm,\r\n families: allowedFamilies,\r\n styles: allowedStyles,\r\n pageSize = 100,\r\n className,\r\n}) => {\r\n const {\r\n loading, searching, error, setSearch,\r\n activeFamily, setActiveFamily, availableFamilies,\r\n activeStyle, setActiveStyle, availableStyles,\r\n pageIcons, page, setPage, totalPages, totalCount,\r\n } = useIconSearch({ families: allowedFamilies, styles: allowedStyles, pageSize });\r\n\r\n const inputRef = useRef<HTMLInputElement>(null);\r\n const parsed = value ? parseFaClass(value) : null;\r\n const [hoveredId, setHoveredId] = useState<string | null>(null);\r\n\r\n useEffect(() => { inputRef.current?.focus(); }, [loading]);\r\n\r\n const handleSelect = useCallback((id: string) => {\r\n const family = activeFamily;\r\n const style: IconStyle | null = family === 'brands' ? null : (activeStyle || 'solid');\r\n const icon: IconSelection = {\r\n name: toFaClass(id, family, style),\r\n family,\r\n style,\r\n label: id,\r\n };\r\n onSelect?.(icon);\r\n onConfirm?.(icon);\r\n }, [onSelect, onConfirm, activeFamily, activeStyle]);\r\n\r\n if (loading) {\r\n return (\r\n <div className={cn('flex flex-col items-center justify-center py-12 gap-3', className)}>\r\n <Loader2 className=\"w-6 h-6 animate-spin text-muted-foreground\" />\r\n <p className=\"text-sm text-muted-foreground\">Loading icons…</p>\r\n </div>\r\n );\r\n }\r\n\r\n if (error) {\r\n return (\r\n <div className={cn('flex flex-col items-center justify-center py-12 gap-3', className)}>\r\n <AlertCircle className=\"w-6 h-6 text-destructive\" />\r\n <p className=\"text-sm text-destructive\">{error}</p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className={cn('space-y-3', className)}>\r\n {/* Search */}\r\n <div className=\"relative\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground\" />\r\n {searching && <Loader2 className=\"absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 animate-spin text-muted-foreground\" />}\r\n <input\r\n ref={inputRef}\r\n type=\"text\"\r\n placeholder=\"Search icons…\"\r\n onChange={(e) => setSearch(e.target.value)}\r\n className=\"w-full pl-9 pr-9 py-2 text-sm rounded-md border border-border bg-transparent focus:outline-none focus:ring-1 focus:ring-ring\"\r\n />\r\n </div>\r\n\r\n {/* Family tabs (primary) */}\r\n {availableFamilies.length > 1 && (\r\n <div className=\"flex gap-1 border-b border-border pb-2\">\r\n {availableFamilies.map((f) => (\r\n <button\r\n key={f}\r\n onClick={() => setActiveFamily(f)}\r\n className={cn(\r\n 'px-3 py-1.5 text-xs font-semibold rounded-md transition-colors',\r\n f === activeFamily\r\n ? 'bg-primary text-primary-foreground'\r\n : 'text-muted-foreground hover:bg-accent hover:text-accent-foreground'\r\n )}\r\n >\r\n {FAMILY_LABELS[f]}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Style pills (secondary) — not shown for Brands */}\r\n {availableStyles.length > 1 && (\r\n <div className=\"flex gap-1 flex-wrap items-center\">\r\n <button\r\n onClick={() => setActiveStyle(null)}\r\n className={cn(\r\n 'px-2.5 py-1 text-xs font-medium rounded-full transition-colors',\r\n !activeStyle\r\n ? 'bg-foreground text-background'\r\n : 'bg-muted text-muted-foreground hover:bg-accent'\r\n )}\r\n >\r\n All\r\n </button>\r\n {availableStyles.map((s) => (\r\n <button\r\n key={s}\r\n onClick={() => setActiveStyle(s === activeStyle ? null : s)}\r\n className={cn(\r\n 'px-2.5 py-1 text-xs font-medium rounded-full capitalize transition-colors',\r\n s === activeStyle\r\n ? 'bg-foreground text-background'\r\n : 'bg-muted text-muted-foreground hover:bg-accent'\r\n )}\r\n >\r\n {s}\r\n </button>\r\n ))}\r\n <span className=\"ml-auto text-[11px] text-muted-foreground\">\r\n {totalCount} icons\r\n </span>\r\n </div>\r\n )}\r\n\r\n {/* Grid */}\r\n {pageIcons.length === 0 ? (\r\n <div className=\"flex flex-col items-center justify-center py-10 gap-2\">\r\n <Smile className=\"w-6 h-6 text-muted-foreground/40\" />\r\n <p className=\"text-sm text-muted-foreground\">No icons found</p>\r\n </div>\r\n ) : (\r\n <div className=\"grid grid-cols-8 sm:grid-cols-10 md:grid-cols-12 gap-1\">\r\n {pageIcons.map((icon) => {\r\n const isSelected = parsed?.id === icon.id && parsed?.family === activeFamily;\r\n const isHovered = hoveredId === icon.id;\r\n const displayStyle: IconStyle | null = activeFamily === 'brands' ? null : (activeStyle || 'solid');\r\n const cssClass = toFaClass(icon.id, activeFamily, displayStyle);\r\n\r\n return (\r\n <button\r\n key={icon.id}\r\n onClick={() => handleSelect(icon.id)}\r\n onMouseEnter={() => setHoveredId(icon.id)}\r\n onMouseLeave={() => setHoveredId(null)}\r\n title={icon.label}\r\n className={cn(\r\n 'aspect-square flex items-center justify-center rounded-md text-base transition-all',\r\n isSelected\r\n ? 'bg-primary/10 text-primary ring-2 ring-primary'\r\n : isHovered\r\n ? 'bg-accent text-accent-foreground scale-110'\r\n : 'text-muted-foreground hover:bg-accent/50'\r\n )}\r\n >\r\n <i className={cssClass} />\r\n </button>\r\n );\r\n })}\r\n </div>\r\n )}\r\n\r\n {/* Hover preview — fixed height to prevent layout shift */}\r\n <div className=\"h-6 text-center\">\r\n {hoveredId && (\r\n <code className=\"text-[11px] text-muted-foreground bg-muted px-2 py-0.5 rounded\">\r\n fa-{hoveredId}\r\n </code>\r\n )}\r\n </div>\r\n\r\n {/* Pagination */}\r\n {totalPages > 1 && (\r\n <div className=\"flex items-center justify-center gap-2\">\r\n <button\r\n onClick={() => setPage(Math.max(0, page - 1))}\r\n disabled={page === 0}\r\n className=\"p-1 rounded hover:bg-accent disabled:opacity-30 transition-colors\"\r\n >\r\n <ChevronLeft className=\"w-4 h-4\" />\r\n </button>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {page + 1} / {totalPages}\r\n </span>\r\n <button\r\n onClick={() => setPage(Math.min(totalPages - 1, page + 1))}\r\n disabled={page >= totalPages - 1}\r\n className=\"p-1 rounded hover:bg-accent disabled:opacity-30 transition-colors\"\r\n >\r\n <ChevronRight className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Dialog wrapper\r\n// ---------------------------------------------------------------------------\r\nconst PickerDialog: React.FC<{\r\n open: boolean;\r\n onClose: () => void;\r\n children: React.ReactNode;\r\n}> = ({ open, onClose, children }) => {\r\n if (!open) return null;\r\n return (\r\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\r\n <div className=\"absolute inset-0 bg-black/50 backdrop-blur-sm\" onClick={onClose} />\r\n <div className=\"relative z-10 w-full max-w-xl max-h-[80vh] bg-background rounded-xl shadow-2xl border border-border flex flex-col overflow-hidden mx-4\">\r\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border\">\r\n <h3 className=\"text-sm font-semibold text-foreground\">Select Icon</h3>\r\n <button onClick={onClose} className=\"p-1 rounded hover:bg-accent transition-colors\">\r\n <X className=\"w-4 h-4 text-muted-foreground\" />\r\n </button>\r\n </div>\r\n <div className=\"flex-1 overflow-y-auto p-4\">{children}</div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Public API\r\n// ---------------------------------------------------------------------------\r\nexport const IconPicker: React.FC<IconPickerProps> = (props) => {\r\n const { mode = 'inline', trigger, open: controlledOpen, onClose, value, onSelect, className, ...rest } = props;\r\n\r\n const [internalOpen, setInternalOpen] = useState(false);\r\n const isOpen = controlledOpen ?? internalOpen;\r\n\r\n const handleClose = useCallback(() => {\r\n setInternalOpen(false);\r\n onClose?.();\r\n }, [onClose]);\r\n\r\n const handleSelectAndClose = useCallback((icon: IconSelection) => {\r\n onSelect?.(icon);\r\n handleClose();\r\n }, [onSelect, handleClose]);\r\n\r\n // Inline mode\r\n if (mode === 'inline') {\r\n return <IconPickerContent value={value} onSelect={onSelect} className={className} {...rest} />;\r\n }\r\n\r\n // Dialog mode\r\n const parsed = value ? parseFaClass(value) : null;\r\n const triggerElement = trigger || (\r\n <div className={cn(\r\n 'inline-flex items-center gap-2 px-3 py-2 rounded-md border border-border cursor-pointer',\r\n 'hover:border-ring transition-colors',\r\n className,\r\n )}>\r\n {parsed ? (\r\n <>\r\n <i className={value!} />\r\n <span className=\"text-sm text-muted-foreground\">fa-{parsed.id}</span>\r\n </>\r\n ) : (\r\n <span className=\"text-sm text-muted-foreground\">Choose icon…</span>\r\n )}\r\n <ChevronRight className=\"w-3.5 h-3.5 text-muted-foreground ml-auto\" />\r\n </div>\r\n );\r\n\r\n return (\r\n <>\r\n <span onClick={() => setInternalOpen(true)} className=\"cursor-pointer\">{triggerElement}</span>\r\n <PickerDialog open={isOpen} onClose={handleClose}>\r\n <IconPickerContent value={value} onSelect={handleSelectAndClose} {...rest} />\r\n </PickerDialog>\r\n </>\r\n );\r\n};\r\n"]}