feat(frontend): Implement configurable navbar component
Add fully customizable navbar component that renders on frontend using settings from admin panel. Features: - 38 configurable options (colors, typography, spacing, effects) - Responsive breakpoint support (sm, md, lg, xl, xxl) - Position modes: sticky, static, fixed - Let's Talk button with icon support - Dropdown hover effects for desktop - Mobile hamburger menu integration - Bootstrap 5.3 compatible - Box shadow and hover effects File: template-parts/navbar-configurable.php 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
302
template-parts/navbar-configurable.php
Normal file
302
template-parts/navbar-configurable.php
Normal file
@@ -0,0 +1,302 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Template Part: Navbar Configurable
|
||||||
|
*
|
||||||
|
* @package Apus_Theme
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Obtener configuración usando Settings Manager
|
||||||
|
$settings_manager = new APUS_Settings_Manager();
|
||||||
|
$settings = $settings_manager->get_settings();
|
||||||
|
|
||||||
|
// Extraer configuración del componente
|
||||||
|
$navbar_config = isset($settings['components']['navbar'])
|
||||||
|
? $settings['components']['navbar']
|
||||||
|
: array();
|
||||||
|
|
||||||
|
// Los defaults ya están en Settings Manager, pero por seguridad validar
|
||||||
|
$defaults = array(
|
||||||
|
'enabled' => true,
|
||||||
|
'show_on_mobile' => true,
|
||||||
|
'show_on_desktop' => true,
|
||||||
|
'position' => 'sticky',
|
||||||
|
'responsive_breakpoint' => 'lg',
|
||||||
|
'enable_box_shadow' => true,
|
||||||
|
'enable_underline_effect' => true,
|
||||||
|
'enable_hover_background' => true,
|
||||||
|
|
||||||
|
'lets_talk_button' => array(
|
||||||
|
'enabled' => true,
|
||||||
|
'text' => "Let's Talk",
|
||||||
|
'icon_class' => 'bi bi-lightning-charge-fill',
|
||||||
|
'show_icon' => true,
|
||||||
|
'position' => 'right'
|
||||||
|
),
|
||||||
|
|
||||||
|
'dropdown' => array(
|
||||||
|
'enable_hover_desktop' => true,
|
||||||
|
'max_height' => 70,
|
||||||
|
'border_radius' => 8,
|
||||||
|
'item_padding_vertical' => 0.5,
|
||||||
|
'item_padding_horizontal' => 1.25
|
||||||
|
),
|
||||||
|
|
||||||
|
'custom_styles' => array(
|
||||||
|
'background_color' => '#1e3a5f',
|
||||||
|
'text_color' => '#ffffff',
|
||||||
|
'link_hover_color' => '#FF8600',
|
||||||
|
'link_hover_bg_color' => '#FF8600',
|
||||||
|
'dropdown_bg_color' => '#ffffff',
|
||||||
|
'dropdown_item_color' => '#4A5568',
|
||||||
|
'dropdown_item_hover_color' => '#FF8600',
|
||||||
|
'font_size' => 'normal',
|
||||||
|
'font_weight' => '500',
|
||||||
|
'box_shadow_intensity' => 'normal',
|
||||||
|
'border_radius' => 4,
|
||||||
|
'padding_vertical' => 0.75,
|
||||||
|
'link_padding_vertical' => 0.5,
|
||||||
|
'link_padding_horizontal' => 0.65,
|
||||||
|
'z_index' => 1030,
|
||||||
|
'transition_speed' => 'normal'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Merge con defaults (por si acaso)
|
||||||
|
$config = wp_parse_args($navbar_config, $defaults);
|
||||||
|
|
||||||
|
// Verificar si está habilitado
|
||||||
|
if (!$config['enabled']) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construir clases CSS
|
||||||
|
$classes = array('navbar', 'navbar-expand-' . $config['responsive_breakpoint'], 'navbar-dark');
|
||||||
|
|
||||||
|
// Visibilidad responsive
|
||||||
|
if (!$config['show_on_mobile']) {
|
||||||
|
$classes[] = 'd-none';
|
||||||
|
$classes[] = 'd-' . $config['responsive_breakpoint'] . '-block';
|
||||||
|
}
|
||||||
|
if (!$config['show_on_desktop']) {
|
||||||
|
$classes[] = 'd-' . $config['responsive_breakpoint'] . '-none';
|
||||||
|
}
|
||||||
|
|
||||||
|
$class_attr = implode(' ', $classes);
|
||||||
|
|
||||||
|
// Construir estilos inline
|
||||||
|
$inline_styles = array();
|
||||||
|
|
||||||
|
// Background color
|
||||||
|
if (!empty($config['custom_styles']['background_color'])) {
|
||||||
|
$inline_styles[] = 'background-color: ' . esc_attr($config['custom_styles']['background_color']) . ' !important';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Posición
|
||||||
|
$position_map = array(
|
||||||
|
'sticky' => 'sticky',
|
||||||
|
'static' => 'static',
|
||||||
|
'fixed' => 'fixed'
|
||||||
|
);
|
||||||
|
if (isset($position_map[$config['position']])) {
|
||||||
|
$inline_styles[] = 'position: ' . $position_map[$config['position']];
|
||||||
|
if ($config['position'] !== 'static') {
|
||||||
|
$inline_styles[] = 'top: 0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Z-index
|
||||||
|
$inline_styles[] = 'z-index: ' . absint($config['custom_styles']['z_index']);
|
||||||
|
|
||||||
|
// Padding
|
||||||
|
$inline_styles[] = 'padding: ' . floatval($config['custom_styles']['padding_vertical']) . 'rem 0';
|
||||||
|
|
||||||
|
// Box shadow
|
||||||
|
if ($config['enable_box_shadow']) {
|
||||||
|
$shadow_map = array(
|
||||||
|
'none' => 'none',
|
||||||
|
'light' => '0 2px 6px rgba(30, 58, 95, 0.08)',
|
||||||
|
'normal' => '0 4px 12px rgba(30, 58, 95, 0.15)',
|
||||||
|
'strong' => '0 6px 20px rgba(30, 58, 95, 0.25)'
|
||||||
|
);
|
||||||
|
if (isset($shadow_map[$config['custom_styles']['box_shadow_intensity']])) {
|
||||||
|
$inline_styles[] = 'box-shadow: ' . $shadow_map[$config['custom_styles']['box_shadow_intensity']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transition
|
||||||
|
$transition_map = array(
|
||||||
|
'fast' => '0.2s',
|
||||||
|
'normal' => '0.3s',
|
||||||
|
'slow' => '0.5s'
|
||||||
|
);
|
||||||
|
if (isset($transition_map[$config['custom_styles']['transition_speed']])) {
|
||||||
|
$inline_styles[] = 'transition: all ' . $transition_map[$config['custom_styles']['transition_speed']] . ' ease';
|
||||||
|
}
|
||||||
|
|
||||||
|
$style_attr = !empty($inline_styles) ? ' style="' . implode('; ', $inline_styles) . '"' : '';
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php if (!empty($config['custom_styles'])): ?>
|
||||||
|
<style>
|
||||||
|
/* Navbar custom styles */
|
||||||
|
.navbar {
|
||||||
|
<?php if (!empty($config['custom_styles']['text_color'])): ?>
|
||||||
|
--navbar-link-color: <?php echo esc_attr($config['custom_styles']['text_color']); ?>;
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (!empty($config['custom_styles']['link_hover_color'])): ?>
|
||||||
|
--navbar-link-hover-color: <?php echo esc_attr($config['custom_styles']['link_hover_color']); ?>;
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (!empty($config['custom_styles']['link_hover_bg_color'])): ?>
|
||||||
|
--navbar-link-hover-bg: <?php echo esc_attr($config['custom_styles']['link_hover_bg_color']); ?>1a;
|
||||||
|
<?php endif; ?>
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .nav-link {
|
||||||
|
color: var(--navbar-link-color, rgba(255, 255, 255, 0.9)) !important;
|
||||||
|
padding: <?php echo floatval($config['custom_styles']['link_padding_vertical']); ?>rem
|
||||||
|
<?php echo floatval($config['custom_styles']['link_padding_horizontal']); ?>rem !important;
|
||||||
|
font-size: <?php
|
||||||
|
$font_sizes = array('small' => '0.8rem', 'normal' => '0.9rem', 'large' => '1rem');
|
||||||
|
echo isset($font_sizes[$config['custom_styles']['font_size']])
|
||||||
|
? $font_sizes[$config['custom_styles']['font_size']]
|
||||||
|
: '0.9rem';
|
||||||
|
?>;
|
||||||
|
font-weight: <?php echo esc_attr($config['custom_styles']['font_weight']); ?>;
|
||||||
|
border-radius: <?php echo absint($config['custom_styles']['border_radius']); ?>px;
|
||||||
|
}
|
||||||
|
|
||||||
|
<?php if ($config['enable_hover_background']): ?>
|
||||||
|
.navbar .nav-link:hover {
|
||||||
|
color: var(--navbar-link-hover-color, #FF8600) !important;
|
||||||
|
background-color: var(--navbar-link-hover-bg, rgba(255, 133, 0, 0.1));
|
||||||
|
}
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ($config['enable_underline_effect']): ?>
|
||||||
|
.navbar .nav-link::after {
|
||||||
|
background: var(--navbar-link-hover-color, #FF8600);
|
||||||
|
}
|
||||||
|
.navbar .nav-link:hover::after {
|
||||||
|
transform: translateX(-50%) scaleX(1);
|
||||||
|
}
|
||||||
|
<?php else: ?>
|
||||||
|
.navbar .nav-link::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
/* Dropdown styles */
|
||||||
|
.navbar .dropdown-menu {
|
||||||
|
<?php if (!empty($config['custom_styles']['dropdown_bg_color'])): ?>
|
||||||
|
background-color: <?php echo esc_attr($config['custom_styles']['dropdown_bg_color']); ?>;
|
||||||
|
<?php endif; ?>
|
||||||
|
max-height: <?php echo absint($config['dropdown']['max_height']); ?>vh;
|
||||||
|
border-radius: <?php echo absint($config['dropdown']['border_radius']); ?>px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .dropdown-item {
|
||||||
|
<?php if (!empty($config['custom_styles']['dropdown_item_color'])): ?>
|
||||||
|
color: <?php echo esc_attr($config['custom_styles']['dropdown_item_color']); ?>;
|
||||||
|
<?php endif; ?>
|
||||||
|
padding: <?php echo floatval($config['dropdown']['item_padding_vertical']); ?>rem
|
||||||
|
<?php echo floatval($config['dropdown']['item_padding_horizontal']); ?>rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .dropdown-item:hover {
|
||||||
|
<?php if (!empty($config['custom_styles']['dropdown_item_hover_color'])): ?>
|
||||||
|
color: <?php echo esc_attr($config['custom_styles']['dropdown_item_hover_color']); ?>;
|
||||||
|
<?php endif; ?>
|
||||||
|
}
|
||||||
|
|
||||||
|
<?php if (!$config['dropdown']['enable_hover_desktop']): ?>
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.navbar .nav-item:hover > .dropdown-menu {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<?php endif; ?>
|
||||||
|
</style>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<!-- Navbar Configurable -->
|
||||||
|
<nav class="<?php echo esc_attr($class_attr); ?>"<?php echo $style_attr; ?>
|
||||||
|
role="navigation"
|
||||||
|
aria-label="<?php esc_attr_e('Primary Navigation', 'apus-theme'); ?>">
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<!-- Hamburger Toggle Button -->
|
||||||
|
<button class="navbar-toggler"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#navbarSupportedContent"
|
||||||
|
aria-controls="navbarSupportedContent"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-label="<?php esc_attr_e('Toggle navigation', 'apus-theme'); ?>">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Collapsible Menu -->
|
||||||
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
<?php
|
||||||
|
if (has_nav_menu('primary')) {
|
||||||
|
wp_nav_menu(array(
|
||||||
|
'theme_location' => 'primary',
|
||||||
|
'container' => false,
|
||||||
|
'menu_class' => 'navbar-nav mb-2 mb-lg-0',
|
||||||
|
'fallback_cb' => false,
|
||||||
|
'depth' => 2,
|
||||||
|
'walker' => new WP_Bootstrap_Navwalker(),
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
// Fallback si no hay menú asignado
|
||||||
|
?>
|
||||||
|
<ul class="navbar-nav mb-2 mb-lg-0">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="<?php echo esc_url(home_url('/')); ?>">
|
||||||
|
<?php esc_html_e('Home', 'apus-theme'); ?>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="<?php echo esc_url(get_post_type_archive_link('post')); ?>">
|
||||||
|
<?php esc_html_e('Blog', 'apus-theme'); ?>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!-- Let's Talk Button -->
|
||||||
|
<?php if ($config['lets_talk_button']['enabled']): ?>
|
||||||
|
<?php
|
||||||
|
$button_position_class = '';
|
||||||
|
switch ($config['lets_talk_button']['position']) {
|
||||||
|
case 'left':
|
||||||
|
$button_position_class = 'me-auto';
|
||||||
|
break;
|
||||||
|
case 'center':
|
||||||
|
$button_position_class = 'mx-auto';
|
||||||
|
break;
|
||||||
|
case 'right':
|
||||||
|
default:
|
||||||
|
$button_position_class = 'ms-lg-3';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<button class="btn btn-lets-talk <?php echo esc_attr($button_position_class); ?>"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-target="#contactModal">
|
||||||
|
<?php if ($config['lets_talk_button']['show_icon'] && !empty($config['lets_talk_button']['icon_class'])): ?>
|
||||||
|
<i class="<?php echo esc_attr($config['lets_talk_button']['icon_class']); ?> me-2"></i>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php echo esc_html($config['lets_talk_button']['text']); ?>
|
||||||
|
</button>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div><!-- .container -->
|
||||||
|
</nav><!-- .navbar -->
|
||||||
Reference in New Issue
Block a user