Skip to content

feat: migrate icon system from lucide-react to doo-iconik#110

Open
yamyr wants to merge 1 commit into
mainfrom
feat/doo-iconik-migration
Open

feat: migrate icon system from lucide-react to doo-iconik#110
yamyr wants to merge 1 commit into
mainfrom
feat/doo-iconik-migration

Conversation

@yamyr

@yamyr yamyr commented Mar 16, 2026

Copy link
Copy Markdown
Member

Summary

Replaces the entire lucide-react icon system with hand-drawn doodle-style icons from ajentik/doo-iconik (MIT), giving AskSUSSi a distinctive, cohesive visual identity.

  • 44 unique lucide-react icons + 12 inline SVGs migrated across 19 component files
  • Introduces a typed bridge module at src/lib/icons/ with a <DooIcon name="..." /> component
  • Removes lucide-react dependency entirely (~577KB saved from node_modules)
  • Zero lint errors, zero TypeScript errors, clean next build

Architecture

Why a bridge module (not npm install)?

@doo-iconik/react is not yet published to npm. The monorepo uses workspace file: links that npm cannot resolve from git URLs. Instead, we extract a 60-icon subset from the upstream source-of-truth into src/lib/icons/icon-data.ts:

src/lib/icons/
├── DooIcon.tsx      # 60-line forwardRef component (SSR-safe)
├── icon-data.ts     # 60 icons extracted from @doo-iconik/core (516 lines)
└── index.ts         # Barrel export

This gives us:

  • Full TypeScript safety (IconName union type)
  • Zero external runtime dependency
  • aria-hidden="true" by default on all icons
  • Supports size, className, and all standard SVG props

Migration map (selected)

Lucide doo-iconik Used in
MapPin location-pin POIPopup, POICard, VenueCard, ToolResultCard, Onboarding
Send send ChatInput, EventPopup, HeroIntro
Calendar calendar POIPopup, ToolResultCard, EventPopup, Onboarding
Navigation navigation POIPopup, POICard, VenueCard, EventCard
X cross Onboarding, POIPopup, EventPopup, AerialViewButton
Star star POIPopup, POICard, VenueCard, ToolResultCard
+ 38 more

Dynamic icon patterns preserved

  • VenueCard.tsx: categoryIconMap: Record<string, IconName> replaces Record<string, LucideIcon>
  • Onboarding.tsx: CAPABILITIES array uses IconName string literals instead of component references
  • sonner.tsx: Toast icons (success/info/warning/error/loading) all use DooIcon

Files changed (26)

New

  • src/lib/icons/DooIcon.tsx — Bridge component
  • src/lib/icons/icon-data.ts — Icon data subset (60 icons from 592)
  • src/lib/icons/index.ts — Barrel export

Modified (19 components)

  • src/components/layout/AppShell.tsx
  • src/components/layout/HeroIntro.tsx
  • src/components/layout/Onboarding.tsx
  • src/components/chat/ChatInput.tsx
  • src/components/chat/ChatPanel.tsx
  • src/components/chat/VoiceButton.tsx
  • src/components/chat/ToolResultCard.tsx
  • src/components/map/POIPopup.tsx
  • src/components/map/EventPopup.tsx
  • src/components/map/AerialViewButton.tsx
  • src/components/map/StreetViewPanel.tsx
  • src/components/events/EventCard.tsx
  • src/components/events/EventsPanel.tsx
  • src/components/ui/POICard.tsx
  • src/components/ui/VenueCard.tsx
  • src/components/ui/select.tsx
  • src/components/ui/sonner.tsx
  • src/components/ui/error-state.tsx
  • src/components/ui/empty-state.tsx

Updated docs

  • .specify/memory/constitution.md — Icon convention updated
  • README.md — Tech stack constraint updated
  • package.jsonlucide-react removed

Validation

Check Result
npm run lint 0 errors (4 pre-existing warnings)
npm run build ✅ Compiled in 3.2s
npx tsc --noEmit 0 errors
grep -r lucide-react src/ 0 matches

Related issues

Not in scope (intentional)

  • QuickActions.tsx emoji pseudo-icons (🗺️ 📅 🍔 📚 🚌 🏥) — kept as-is, properly aria-hidden
  • Brand logos (/suss-logo.png) — not icons, out of scope

Replace all lucide-react icons (44 unique across 19 files) and 12 inline
SVGs with the doo-iconik hand-drawn icon set via a typed bridge module.

- Add src/lib/icons/ bridge: DooIcon component + 60-icon data subset
  extracted from ajentik/doo-iconik (MIT)
- Migrate 19 component files to use <DooIcon name="..." />
- Remove lucide-react dependency (-577KB from bundle)
- Update constitution and README to reflect new icon convention
- Fix a11y: DooIcon defaults to aria-hidden="true" for decorative icons
- Zero lint errors, zero type errors, build passes clean
@yamyr yamyr force-pushed the feat/doo-iconik-migration branch from bfb528a to 2f5b363 Compare March 17, 2026 06:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant