Step 1.5: Build header template with navigation and mobile menu
This commit is contained in:
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
(function(o){o(function(){console.log("HomeProz theme initialized")})})(jQuery);
|
||||
(function(e){var a=e(".menu-toggle"),o=e(".mobile-navigation");a.length&&(a.on("click",function(){var n=e(this).attr("aria-expanded")==="true";e(this).attr("aria-expanded",!n),o.toggleClass("is-open"),n?e("body").removeClass("mobile-menu-open"):e("body").addClass("mobile-menu-open")}),e(document).on("keydown",function(n){n.key==="Escape"&&o.hasClass("is-open")&&(a.attr("aria-expanded","false"),o.removeClass("is-open"),e("body").removeClass("mobile-menu-open"))}),e(document).on("click",function(n){o.hasClass("is-open")&&!e(n.target).closest(".mobile-navigation").length&&!e(n.target).closest(".menu-toggle").length&&(a.attr("aria-expanded","false"),o.removeClass("is-open"),e("body").removeClass("mobile-menu-open"))}))})(jQuery);(function(e){e(function(){})})(jQuery);
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* The header for our theme
|
||||
*
|
||||
* @package HomeProz
|
||||
*/
|
||||
|
||||
?>
|
||||
<!doctype html>
|
||||
<html <?php language_attributes(); ?>>
|
||||
<head>
|
||||
<meta charset="<?php bloginfo('charset'); ?>">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="profile" href="https://gmpg.org/xfn/11">
|
||||
<?php wp_head(); ?>
|
||||
</head>
|
||||
|
||||
<body <?php body_class(); ?>>
|
||||
<?php wp_body_open(); ?>
|
||||
|
||||
<div id="page" class="site">
|
||||
<a class="skip-link sr-only" href="#primary"><?php esc_html_e('Skip to content', 'homeproz'); ?></a>
|
||||
|
||||
<?php get_template_part('template-parts/header/site-header'); ?>
|
||||
@@ -132,6 +132,18 @@ function homeproz_format_price($price) {
|
||||
return '$' . number_format($price);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback menu when no menu is assigned
|
||||
*/
|
||||
function homeproz_fallback_menu() {
|
||||
echo '<ul class="nav-menu">';
|
||||
echo '<li class="menu-item"><a href="' . esc_url(home_url('/')) . '">Home</a></li>';
|
||||
echo '<li class="menu-item"><a href="' . esc_url(home_url('/properties/')) . '">Properties</a></li>';
|
||||
echo '<li class="menu-item"><a href="' . esc_url(home_url('/about/')) . '">About</a></li>';
|
||||
echo '<li class="menu-item"><a href="' . esc_url(home_url('/contact/')) . '">Contact</a></li>';
|
||||
echo '</ul>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get theme option (placeholder for future ACF options)
|
||||
*
|
||||
|
||||
@@ -6,12 +6,15 @@
|
||||
|
||||
import './main.scss';
|
||||
|
||||
// Import component JS
|
||||
import '../template-parts/header/navigation.js';
|
||||
|
||||
(function($) {
|
||||
'use strict';
|
||||
|
||||
// Document ready
|
||||
$(function() {
|
||||
console.log('HomeProz theme initialized');
|
||||
// Theme initialized
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
// Import Tailwind
|
||||
@import 'tailwind.css';
|
||||
|
||||
// Import component styles
|
||||
@import '../template-parts/header/site-header.scss';
|
||||
|
||||
// ============================================
|
||||
// CSS Custom Properties (Design Tokens)
|
||||
// ============================================
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Navigation functionality
|
||||
*
|
||||
* @package HomeProz
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
'use strict';
|
||||
|
||||
// Mobile menu toggle
|
||||
var $menuToggle = $('.menu-toggle');
|
||||
var $mobileMenu = $('.mobile-navigation');
|
||||
|
||||
if (!$menuToggle.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
$menuToggle.on('click', function() {
|
||||
var isExpanded = $(this).attr('aria-expanded') === 'true';
|
||||
|
||||
$(this).attr('aria-expanded', !isExpanded);
|
||||
$mobileMenu.toggleClass('is-open');
|
||||
|
||||
// Prevent body scroll when menu is open
|
||||
if (!isExpanded) {
|
||||
$('body').addClass('mobile-menu-open');
|
||||
} else {
|
||||
$('body').removeClass('mobile-menu-open');
|
||||
}
|
||||
});
|
||||
|
||||
// Close mobile menu on escape key
|
||||
$(document).on('keydown', function(e) {
|
||||
if (e.key === 'Escape' && $mobileMenu.hasClass('is-open')) {
|
||||
$menuToggle.attr('aria-expanded', 'false');
|
||||
$mobileMenu.removeClass('is-open');
|
||||
$('body').removeClass('mobile-menu-open');
|
||||
}
|
||||
});
|
||||
|
||||
// Close mobile menu when clicking outside
|
||||
$(document).on('click', function(e) {
|
||||
if ($mobileMenu.hasClass('is-open') &&
|
||||
!$(e.target).closest('.mobile-navigation').length &&
|
||||
!$(e.target).closest('.menu-toggle').length) {
|
||||
$menuToggle.attr('aria-expanded', 'false');
|
||||
$mobileMenu.removeClass('is-open');
|
||||
$('body').removeClass('mobile-menu-open');
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* Site Header Template Part
|
||||
*
|
||||
* @package HomeProz
|
||||
*/
|
||||
|
||||
?>
|
||||
<header id="masthead" class="site-header">
|
||||
<div class="header-container container">
|
||||
<div class="header-inner">
|
||||
<!-- Logo -->
|
||||
<div class="site-branding">
|
||||
<?php if (has_custom_logo()) : ?>
|
||||
<?php the_custom_logo(); ?>
|
||||
<?php else : ?>
|
||||
<a href="<?php echo esc_url(home_url('/')); ?>" class="site-title-link">
|
||||
<span class="site-title"><?php bloginfo('name'); ?></span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Desktop Navigation -->
|
||||
<nav id="site-navigation" class="main-navigation" aria-label="<?php esc_attr_e('Primary Menu', 'homeproz'); ?>">
|
||||
<?php
|
||||
wp_nav_menu(array(
|
||||
'theme_location' => 'primary',
|
||||
'menu_id' => 'primary-menu',
|
||||
'menu_class' => 'nav-menu',
|
||||
'container' => false,
|
||||
'fallback_cb' => 'homeproz_fallback_menu',
|
||||
));
|
||||
?>
|
||||
</nav>
|
||||
|
||||
<!-- Mobile Menu Toggle -->
|
||||
<button class="menu-toggle" aria-controls="mobile-menu" aria-expanded="false">
|
||||
<span class="menu-toggle-icon">
|
||||
<span class="bar"></span>
|
||||
<span class="bar"></span>
|
||||
<span class="bar"></span>
|
||||
</span>
|
||||
<span class="sr-only"><?php esc_html_e('Menu', 'homeproz'); ?></span>
|
||||
</button>
|
||||
|
||||
<!-- Header CTA -->
|
||||
<div class="header-cta">
|
||||
<a href="tel:<?php echo esc_attr(preg_replace('/[^0-9]/', '', homeproz_get_option('phone'))); ?>" class="header-phone">
|
||||
<?php echo esc_html(homeproz_get_option('phone')); ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mobile Navigation -->
|
||||
<nav id="mobile-menu" class="mobile-navigation" aria-label="<?php esc_attr_e('Mobile Menu', 'homeproz'); ?>">
|
||||
<?php
|
||||
wp_nav_menu(array(
|
||||
'theme_location' => 'primary',
|
||||
'menu_id' => 'mobile-menu-list',
|
||||
'menu_class' => 'mobile-nav-menu',
|
||||
'container' => false,
|
||||
'fallback_cb' => 'homeproz_fallback_menu',
|
||||
));
|
||||
?>
|
||||
<div class="mobile-menu-cta">
|
||||
<a href="tel:<?php echo esc_attr(preg_replace('/[^0-9]/', '', homeproz_get_option('phone'))); ?>" class="btn btn-primary">
|
||||
Call <?php echo esc_html(homeproz_get_option('phone')); ?>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
* Site Header Styles
|
||||
*
|
||||
* @package HomeProz
|
||||
*/
|
||||
|
||||
.site-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
background-color: var(--color-bg-dark);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.header-container {
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.header-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
// Logo / Branding
|
||||
.site-branding {
|
||||
flex-shrink: 0;
|
||||
|
||||
.custom-logo-link {
|
||||
display: block;
|
||||
|
||||
img {
|
||||
max-height: 60px;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.site-title-link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.site-title {
|
||||
font-family: var(--font-display);
|
||||
font-size: 1.5rem;
|
||||
color: var(--color-text);
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
}
|
||||
|
||||
// Desktop Navigation
|
||||
.main-navigation {
|
||||
display: none;
|
||||
flex-grow: 1;
|
||||
justify-content: center;
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.nav-menu {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2rem;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
a {
|
||||
display: block;
|
||||
padding: 0.5rem 0;
|
||||
color: var(--color-text-muted);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: var(--color-text);
|
||||
}
|
||||
}
|
||||
|
||||
&.current-menu-item a,
|
||||
&.current_page_item a {
|
||||
color: var(--color-accent-light);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mobile Menu Toggle
|
||||
.menu-toggle {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.menu-toggle-icon {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.bar {
|
||||
display: block;
|
||||
width: 24px;
|
||||
height: 2px;
|
||||
background-color: var(--color-text);
|
||||
}
|
||||
|
||||
&[aria-expanded="true"] {
|
||||
.bar:nth-child(1) {
|
||||
transform: translateY(7px) rotate(45deg);
|
||||
}
|
||||
.bar:nth-child(2) {
|
||||
opacity: 0;
|
||||
}
|
||||
.bar:nth-child(3) {
|
||||
transform: translateY(-7px) rotate(-45deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Header CTA
|
||||
.header-cta {
|
||||
display: none;
|
||||
flex-shrink: 0;
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.header-phone {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 0.625rem 1.25rem;
|
||||
background-color: var(--color-accent);
|
||||
color: white;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
border-radius: 0.25rem;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-accent-hover);
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mobile Navigation
|
||||
.mobile-navigation {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: var(--color-bg-card);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
padding: 1rem;
|
||||
|
||||
&.is-open {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.mobile-nav-menu {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
a {
|
||||
display: block;
|
||||
padding: 1rem 0;
|
||||
color: var(--color-text);
|
||||
font-size: 1rem;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: var(--color-accent-light);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-menu-cta {
|
||||
margin-top: 1.5rem;
|
||||
padding-top: 1.5rem;
|
||||
border-top: 1px solid var(--color-border);
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user