From 26a6e32e90efce97ac941731ec8563bb5dec4664 Mon Sep 17 00:00:00 2001 From: Bhagirath00 Date: Sat, 14 Feb 2026 22:46:08 +0530 Subject: [PATCH] feat: implement interactive SVG Hero Header Studio with live preview --- src/components/ElementPalette.tsx | 45 +++++ src/components/HeroHeaderDialog.tsx | 45 +++++ src/components/HeroHeaderMaker.tsx | 300 ++++++++++++++++++++++++++++ 3 files changed, 390 insertions(+) create mode 100644 src/components/HeroHeaderDialog.tsx create mode 100644 src/components/HeroHeaderMaker.tsx diff --git a/src/components/ElementPalette.tsx b/src/components/ElementPalette.tsx index ab9edcb..04ff333 100644 --- a/src/components/ElementPalette.tsx +++ b/src/components/ElementPalette.tsx @@ -16,6 +16,7 @@ import { import { useIsMobile } from '@/hooks/use-mobile'; import { TechStackDialog } from './TechStackDialog'; import { CustomBadgeDialog } from './CustomBadgeDialog'; +import { HeroHeaderDialog } from './HeroHeaderDialog'; import type { ElementType } from '@/types/elements'; interface ElementPaletteProps { @@ -26,6 +27,7 @@ export function ElementPalette({ onAddElement }: ElementPaletteProps) { const [activeTab, setActiveTab] = useState("basic"); const [showTechStackDialog, setShowTechStackDialog] = useState(false); const [showCustomBadgeDialog, setShowCustomBadgeDialog] = useState(false); + const [showHeroHeaderDialog, setShowHeroHeaderDialog] = useState(false); const isMobile = useIsMobile(); // Basic element types @@ -260,6 +262,12 @@ export function ElementPalette({ onAddElement }: ElementPaletteProps) { onAddElement={onAddElement} /> + setShowHeroHeaderDialog(false)} + onAddElement={onAddElement} + /> + Basic @@ -346,6 +354,7 @@ export function ElementPalette({ onAddElement }: ElementPaletteProps) { {/* Advanced Elements Tab */} + {/* Advanced Tech Stack Creator */} {(() => { const button = ( @@ -387,6 +396,42 @@ export function ElementPalette({ onAddElement }: ElementPaletteProps) { GitHub Elements + {/* Hero Header Studio Button */} + {(() => { + const button = ( + + ); + + if (isMobile) { + return
{button}
; + } + + return ( + + + {button} + + +
+ Design a personalized SVG hero banner with waves & animations +
+
+
+ ); + })()} + {advancedElementTypes.map(({ type, label, icon, template }) => { const button = ( + + + +
+ +
+ setFontColor(e.target.value.replace('#', ''))} + className="font-mono text-xs bg-background shrink" + /> + setFontColor(e.target.value.replace('#', ''))} + value={fontColor.startsWith('#') ? fontColor : `#${fontColor}`} + /> + +
+
+ + +
+ + setFontSize(e.target.value)} + className="bg-background" + /> +
+ + + {/* Right: Live Preview */} +
+
+
+ + {isUpdating && Generating SVG...} +
+
+ {/* Grid Pattern Background for transparency check */} +
+ + {previewUrl && ( + Header Preview { + (e.target as HTMLImageElement).src = 'https://img.shields.io/badge/error-api_unavailable-red'; + }} + /> + )} + + {previewUrl && ( +
+ +
+ )} +
+
+ +
+ +
+ {PRESET_COLORS.map((c) => ( + + ))} +
+
+
+
+ +
+ + +
+ + ); +}