getData(); if (!$this->isEnabled($data)) { return ''; } if (!PageVisibilityHelper::shouldShow(self::COMPONENT_NAME)) { return ''; } $html = $this->buildMenu($data); // Si is_critical=true, CSS ya fue inyectado en
por CriticalCSSService $isCritical = $data['visibility']['is_critical'] ?? false; if ($isCritical) { return $html; // Solo HTML, sin CSS inline } // CSS inline para componentes no críticos $css = $this->generateCSS($data); return sprintf("\n%s", $css, $html); } private function isEnabled(array $data): bool { return isset($data['visibility']['is_enabled']) && $data['visibility']['is_enabled'] === true; } private function shouldShowOnMobile(array $data): bool { return isset($data['visibility']['show_on_mobile']) && $data['visibility']['show_on_mobile'] === true; } /** * Generar CSS usando CSSGeneratorService * * Este método es público para que CriticalCSSService pueda * generar CSS crítico antes de wp_head sin duplicar lógica. * * @param array $data Datos del componente * @return string CSS generado */ public function generateCSS(array $data): string { $css = ''; // Obtener valores de configuración $stickyEnabled = $data['visibility']['sticky_enabled'] ?? true; $paddingVertical = $data['layout']['padding_vertical'] ?? '0.75rem 0'; $zIndex = $data['layout']['z_index'] ?? '1030'; $bgColor = $data['colors']['background_color'] ?? '#1e3a5f'; $boxShadow = $data['colors']['box_shadow'] ?? '0 4px 12px rgba(30, 58, 95, 0.15)'; $linkTextColor = $data['links']['text_color'] ?? '#FFFFFF'; $linkHoverColor = $data['links']['hover_color'] ?? '#FF8600'; $linkActiveColor = $data['links']['active_color'] ?? '#FF8600'; $linkFontSize = $data['links']['font_size'] ?? '0.9rem'; $linkFontWeight = $data['links']['font_weight'] ?? '500'; $linkPadding = $data['links']['padding'] ?? '0.5rem 0.65rem'; $linkBorderRadius = $data['links']['border_radius'] ?? '4px'; $showUnderlineEffect = $data['links']['show_underline_effect'] ?? true; $underlineColor = $data['links']['underline_color'] ?? '#FF8600'; // Estilos del navbar container $navbarStyles = [ 'background-color' => $bgColor . ' !important', 'box-shadow' => $boxShadow, 'padding' => $paddingVertical, 'transition' => 'all 0.3s ease', ]; if ($stickyEnabled) { $navbarStyles['position'] = 'sticky'; $navbarStyles['top'] = '0'; $navbarStyles['z-index'] = $zIndex; } $css .= $this->cssGenerator->generate('.navbar', $navbarStyles); // Efecto scrolled del navbar $css .= "\n" . $this->cssGenerator->generate('.navbar.scrolled', [ 'box-shadow' => '0 6px 20px rgba(30, 58, 95, 0.25)', ]); // Estilos de los enlaces del navbar $navLinkStyles = [ 'color' => 'rgba(255, 255, 255, 0.9) !important', 'font-weight' => $linkFontWeight, 'position' => 'relative', 'padding' => $linkPadding . ' !important', 'transition' => 'all 0.3s ease', 'font-size' => $linkFontSize, 'white-space' => 'nowrap', ]; $css .= "\n" . $this->cssGenerator->generate('.navbar .nav-link', $navLinkStyles); // Efecto de subrayado (::after pseudo-element) if ($showUnderlineEffect) { $css .= "\n.navbar .nav-link::after {"; $css .= "\n content: '';"; $css .= "\n position: absolute;"; $css .= "\n bottom: 0;"; $css .= "\n left: 50%;"; $css .= "\n transform: translateX(-50%) scaleX(0);"; $css .= "\n width: 80%;"; $css .= "\n height: 2px;"; $css .= "\n background: {$underlineColor};"; $css .= "\n transition: transform 0.3s ease;"; $css .= "\n}"; $css .= "\n.navbar .nav-link:hover::after {"; $css .= "\n transform: translateX(-50%) scaleX(1);"; $css .= "\n}"; } // Estilos hover y focus de los enlaces $navLinkHoverStyles = [ 'color' => $linkHoverColor . ' !important', 'background-color' => 'rgba(255, 133, 0, 0.1)', 'border-radius' => $linkBorderRadius, ]; $css .= "\n" . $this->cssGenerator->generate('.navbar .nav-link:hover, .navbar .nav-link:focus', $navLinkHoverStyles); // Estilos de enlaces activos $navLinkActiveStyles = [ 'color' => $linkActiveColor . ' !important', ]; $css .= "\n" . $this->cssGenerator->generate('.navbar .nav-link.active, .navbar .nav-item.current-menu-item > .nav-link', $navLinkActiveStyles); // Estilos del dropdown menu $dropdownMaxHeight = $data['visual_effects']['dropdown_max_height'] ?? '300px'; $dropdownStyles = [ 'background' => $data['visual_effects']['background_color'] ?? '#ffffff', 'border' => 'none', 'box-shadow' => $data['visual_effects']['shadow'] ?? '0 8px 24px rgba(0, 0, 0, 0.12)', 'border-radius' => $data['visual_effects']['border_radius'] ?? '8px', 'padding' => '0.5rem 0', 'max-height' => $dropdownMaxHeight, 'overflow-y' => 'auto', ]; $css .= "\n" . $this->cssGenerator->generate('.navbar .dropdown-menu', $dropdownStyles); // Hover en desktop para mostrar dropdown (sin necesidad de clic) $css .= "\n@media (min-width: 992px) {"; $css .= "\n .navbar .dropdown:hover > .dropdown-menu {"; $css .= "\n display: block;"; $css .= "\n margin-top: 0;"; $css .= "\n }"; $css .= "\n}"; // Estilos de items del dropdown $dropdownItemStyles = [ 'color' => $data['visual_effects']['item_color'] ?? '#495057', 'padding' => $data['visual_effects']['item_padding'] ?? '0.625rem 1.25rem', 'transition' => 'all 0.3s ease', 'font-weight' => '500', ]; $css .= "\n" . $this->cssGenerator->generate('.navbar .dropdown-item', $dropdownItemStyles); // Estilos hover de items del dropdown $dropdownItemHoverStyles = [ 'background-color' => $data['visual_effects']['item_hover_background'] ?? 'rgba(255, 133, 0, 0.1)', 'color' => $linkHoverColor, ]; $css .= "\n" . $this->cssGenerator->generate('.navbar .dropdown-item:hover, .navbar .dropdown-item:focus', $dropdownItemHoverStyles); // Estilos del brand (texto) $brandStyles = [ 'color' => ($data['media']['brand_color'] ?? '#FFFFFF') . ' !important', 'font-weight' => '700', 'font-size' => $data['media']['brand_font_size'] ?? '1.5rem', 'transition' => 'color 0.3s ease', ]; $css .= "\n" . $this->cssGenerator->generate('.navbar .navbar-brand, .navbar .roi-navbar-brand', $brandStyles); // Estilos hover del brand $brandHoverStyles = [ 'color' => ($data['media']['brand_hover_color'] ?? '#FF8600') . ' !important', ]; $css .= "\n" . $this->cssGenerator->generate('.navbar .navbar-brand:hover, .navbar .roi-navbar-brand:hover', $brandHoverStyles); // Estilos del logo (imagen) $logoStyles = [ 'height' => $data['media']['logo_height'] ?? '40px', 'width' => 'auto', ]; $css .= "\n" . $this->cssGenerator->generate('.navbar .roi-navbar-logo', $logoStyles); return $css; } private function buildMenu(array $data): string { $menuLocation = $data['behavior']['menu_location'] ?? 'primary'; $enableDropdowns = $data['behavior']['enable_dropdowns'] ?? true; $mobileBreakpoint = $data['behavior']['mobile_breakpoint'] ?? 'lg'; $ulClass = 'navbar-nav mb-2 mb-lg-0'; $args = [ 'theme_location' => $menuLocation === 'custom' ? '' : $menuLocation, 'menu' => $menuLocation === 'custom' ? ($data['behavior']['custom_menu_id'] ?? 0) : '', 'container' => false, 'menu_class' => $ulClass, 'fallback_cb' => '__return_false', 'items_wrap' => '