Files
roi-theme/template-parts/navbar-configurable.php
FrankZamora 3683dc2fb7 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>
2025-11-12 15:26:07 -06:00

303 lines
9.1 KiB
PHP

<?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 -->