feat: modularize header into configurable partial component

This commit is contained in:
Chaoming Li 2024-11-17 23:04:07 +11:00
parent 27b4ffbec1
commit 54801d5d3b
4 changed files with 89 additions and 55 deletions

View file

@ -24,61 +24,7 @@
</head>
<body class="flex flex-col min-h-screen">
<!-- Header -->
<header class="fixed w-full top-0 z-50 bg-white/80 backdrop-blur-sm border-b border-gray-100">
<div class="container">
<nav class="flex items-center justify-between h-20">
<!-- Logo -->
<a href="{{ .Site.BaseURL }}" class="flex items-center">
{{ with .Site.Params.logo }}
<img src="{{ . | relURL }}" alt="{{ $.Site.Title }}" class="h-8">
{{ else }}
<span class="text-xl font-bold text-gray-900">{{ .Site.Title }}</span>
{{ end }}
</a>
<!-- Navigation -->
<div class="hidden md:flex items-center space-x-8">
{{ range .Site.Menus.main }}
<a href="{{ .URL }}" class="text-gray-600 hover:text-primary-600 font-medium transition duration-200">{{ .Name }}</a>
{{ end }}
</div>
<!-- CTA Buttons -->
<div class="hidden md:flex items-center space-x-4">
<a href="{{ .Site.Params.signInURL | default "#" }}" class="inline-flex items-center justify-center px-6 py-3 rounded-lg font-medium transition duration-200 ease-in-out border-2 border-gray-200 hover:border-primary-600 hover:text-primary-600">
Sign in
</a>
<a href="{{ .Site.Params.getStartedURL | default "#" }}" class="inline-flex items-center justify-center px-6 py-3 rounded-lg font-medium transition duration-200 ease-in-out bg-primary-600 text-white hover:bg-primary-700 hover:scale-105">
Get Started
</a>
</div>
<!-- Mobile Menu Button -->
<button class="md:hidden p-2" id="mobile-menu-button" aria-label="Menu">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
</svg>
</button>
</nav>
<!-- Mobile Menu -->
<div class="md:hidden hidden" id="mobile-menu">
<div class="py-4 space-y-4">
{{ range .Site.Menus.main }}
<a href="{{ .URL }}" class="block text-gray-600 hover:text-primary-600 font-medium transition duration-200 py-2">{{ .Name }}</a>
{{ end }}
<div class="pt-4 space-y-4">
<a href="{{ .Site.Params.signInURL | default "#" }}" class="block text-center inline-flex items-center justify-center px-6 py-3 rounded-lg font-medium transition duration-200 ease-in-out border-2 border-gray-200 hover:border-primary-600 hover:text-primary-600">
Sign in
</a>
<a href="{{ .Site.Params.getStartedURL | default "#" }}" class="block text-center inline-flex items-center justify-center px-6 py-3 rounded-lg font-medium transition duration-200 ease-in-out bg-primary-600 text-white hover:bg-primary-700 hover:scale-105">
Get Started
</a>
</div>
</div>
</div>
</div>
</header>
{{ partial "header" . }}
<!-- Main Content -->
<main class="flex-grow pt-20">

View file

@ -0,0 +1,71 @@
{{ $headerConfig := .Site.Params.header }}
<header class="fixed w-full top-0 z-50 {{ with $headerConfig.background }}{{ . }}{{ else }}bg-white/80 backdrop-blur-sm{{ end }} {{ with $headerConfig.border }}{{ . }}{{ else }}border-b border-gray-100{{ end }}">
<div class="container">
<nav class="flex items-center justify-between h-20">
<!-- Logo -->
<a href="{{ .Site.BaseURL }}" class="flex items-center">
{{ with $headerConfig.logo }}
<img src="{{ .src | relURL }}" alt="{{ $.Site.Title }}" class="{{ with .class }}{{ . }}{{ else }}h-8{{ end }}">
{{ else }}
<span class="text-xl font-bold text-gray-900">{{ .Site.Title }}</span>
{{ end }}
</a>
<!-- Navigation -->
<div class="hidden md:flex items-center {{ with $headerConfig.menu.spacing }}{{ . }}{{ else }}space-x-8{{ end }}">
{{ range .Site.Menus.main }}
<a href="{{ .URL }}" class="{{ with $headerConfig.menu.linkClass }}{{ . }}{{ else }}text-gray-600 hover:text-primary-600 font-medium transition duration-200{{ end }}">{{ .Name }}</a>
{{ end }}
</div>
<!-- CTA Buttons -->
{{ if not $headerConfig.hideButtons }}
<div class="hidden md:flex items-center space-x-4">
{{ with $headerConfig.buttons.signIn }}
<a href="{{ .url | default "#" }}" class="{{ with .class }}{{ . }}{{ else }}inline-flex items-center justify-center px-6 py-3 rounded-lg font-medium transition duration-200 ease-in-out border-2 border-gray-200 hover:border-primary-600 hover:text-primary-600{{ end }}">
{{ .text | default "Sign in" }}
</a>
{{ end }}
{{ with $headerConfig.buttons.getStarted }}
<a href="{{ .url | default "#" }}" class="{{ with .class }}{{ . }}{{ else }}inline-flex items-center justify-center px-6 py-3 rounded-lg font-medium transition duration-200 ease-in-out bg-primary-600 text-white hover:bg-primary-700 hover:scale-105{{ end }}">
{{ .text | default "Get Started" }}
</a>
{{ end }}
</div>
{{ end }}
<!-- Mobile Menu Button -->
<button class="md:hidden p-2" id="mobile-menu-button" aria-label="Menu">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
</svg>
</button>
</nav>
<!-- Mobile Menu -->
<div class="md:hidden hidden" id="mobile-menu">
<div class="py-4 space-y-4">
{{ range .Site.Menus.main }}
<a href="{{ .URL }}" class="{{ with $headerConfig.menu.mobileLinkClass }}{{ . }}{{ else }}block text-gray-600 hover:text-primary-600 font-medium transition duration-200 py-2{{ end }}">{{ .Name }}</a>
{{ end }}
{{ if not $headerConfig.hideButtons }}
<div class="pt-4 space-y-4">
{{ with $headerConfig.buttons.signIn }}
<a href="{{ .url | default "#" }}" class="{{ with .mobileClass }}{{ . }}{{ else }}block text-center inline-flex items-center justify-center px-6 py-3 rounded-lg font-medium transition duration-200 ease-in-out border-2 border-gray-200 hover:border-primary-600 hover:text-primary-600{{ end }}">
{{ .text | default "Sign in" }}
</a>
{{ end }}
{{ with $headerConfig.buttons.getStarted }}
<a href="{{ .url | default "#" }}" class="{{ with .mobileClass }}{{ . }}{{ else }}block text-center inline-flex items-center justify-center px-6 py-3 rounded-lg font-medium transition duration-200 ease-in-out bg-primary-600 text-white hover:bg-primary-700 hover:scale-105{{ end }}">
{{ .text | default "Get Started" }}
</a>
{{ end }}
</div>
{{ end }}
</div>
</div>
</div>
</header>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="180" height="48" viewBox="0 0 180 48" xmlns="http://www.w3.org/2000/svg">
<!-- Background shape -->
<path d="M24 8C32.8366 8 40 15.1634 40 24C40 32.8366 32.8366 40 24 40C15.1634 40 8 32.8366 8 24C8 15.1634 15.1634 8 24 8Z" fill="#4F46E5" opacity="0.2"/>
<!-- Geometric accent -->
<path d="M24 12C30.6274 12 36 17.3726 36 24C36 30.6274 30.6274 36 24 36C17.3726 36 12 30.6274 12 24C12 17.3726 17.3726 12 24 12Z" fill="#4F46E5"/>
<!-- Text "Saasfiy" -->
<text x="56" y="32" font-family="Arial, sans-serif" font-weight="bold" font-size="24" fill="#1F2937">
Saasfiy
</text>
<!-- Abstract dots -->
<circle cx="20" cy="24" r="2" fill="white"/>
<circle cx="28" cy="24" r="2" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 773 B