@props([ /** * ============================================================================= * header-background.blade.php — Porto v12 * Componente de Header con imagen/patrón/parallax/video + overlay y animaciones * ============================================================================= * * ➤ Props principales * - title : string | Título principal (permite HTML). * - subtitle : string | Subtítulo opcional (permite HTML). * - breadcrumbs : array | [ ['name'=>..., 'href|route|params'=>..., 'active'=>bool], ... ] * - align : string | left | center | right (layout de columnas) * - size : string | sm | md | lg (alto del header) * - container : string | container | container-fluid * * ➤ Fondo / Modo * - mode : string | image | fixed | parallax | video | pattern * - bgImage : string | URL (img, patrón o poster de video) * - bgPosition : string | CSS background-position (ej: '50% 50%') * - bgPatternClass : string | Clase extra p/ patrones (opcional) * - parallaxSpeed : float | Velocidad (default 1.2) — sólo mode=parallax * - videoPath : string | Ruta del video — sólo mode=video * - videoPosterType : string | 'jpg' | 'png' (default 'jpg') — mode=video * * ➤ Overlay * - overlayColor : string | primary | secondary | tertiary | quaternary | dark | light * - overlayOpacity : string | '0-10' | '0-9' → se mapea a 'overlay-op-X' (string por compat) * - showOverlay : bool | Mostrar/cargar overlay * * ➤ Tipografía y color * - titleColor : string | auto | primary | secondary | tertiary | quaternary | dark | light | * - titleSize : string | sm | md | lg * - uppercaseTitle : bool | TRUE = text-uppercase * - breadcrumbLight : bool | fuerza breadcrumb-light * * ➤ Animaciones (Porto appear-animation) * - titleAnimation : ?string | nombre de animación o null * - titleDelay : int | ms * - titleDuration : ?string | ej: '1s' * - subtitleAnimation: ?string | idem * - subtitleDelay : int | ms * - subtitleDuration : ?string * - crumbAnimation : ?string | idem * - crumbDelay : int | ms * - crumbDuration : ?string * - mediaAnimation : ?string | idem * - mediaDelay : int | ms * - mediaDuration : ?string * - overflowTitle : bool | envuelve

en .overflow-hidden * - overflowSubtitle : bool | idem para subtítulo * - overflowBreadcrumb: bool | idem para breadcrumb * * ➤ Slots * - media : Columna derecha (imágenes, mockups, etc.) * - cta : Botones/acciones bajo el título * * ──────────────────────────────────────────────────────────────────────────── * USO (ejemplos) * --------------------------------------------------------------------------- * 1) Imagen + overlay * * * 2) Parallax + media + CTA * * * Buy Now * * * * * * * 3) Video de fondo * */ // ── Texto y breadcrumbs 'title' => '', 'subtitle' => '', 'breadcrumbs' => [['name' => 'Inicio', 'href' => '/', 'active' => true]], // ── Layout 'align' => 'center', // left | center | right 'size' => 'md', // sm | md | lg 'container' => 'container', // container | container-fluid // ── Fondo / Modo 'mode' => 'image', // image | fixed | parallax | video | pattern 'bgImage' => null, // URL 'bgPosition' => '50% 50%', 'bgPatternClass' => 'page-header-background-pattern', 'parallaxSpeed' => 1.2, 'videoPath' => null, 'videoPosterType' => 'jpg', // ── Overlay 'overlayColor' => 'dark', // primary|secondary|tertiary|quaternary|dark|light 'overlayOpacity' => '7', // '0'..'10' (string por compat con Porto) 'showOverlay' => true, // ── Tipografía 'titleColor' => 'auto', // auto|primary|secondary|tertiary|quaternary|dark|light| 'titleSize' => 'lg', // sm|md|lg (aplica a clase text-*) 'uppercaseTitle' => false, 'breadcrumbLight' => null, // null => auto; true/false fuerza // ── Animaciones 'titleAnimation' => null, 'titleDelay' => 0, 'titleDuration' => null, 'subtitleAnimation' => null, 'subtitleDelay' => 0, 'subtitleDuration' => null, 'crumbAnimation' => null, 'crumbDelay' => 0, 'crumbDuration' => null, 'mediaAnimation' => null, 'mediaDelay' => 0, 'mediaDuration' => null, 'overflowTitle' => false, 'overflowSubtitle' => false, 'overflowBreadcrumb'=> false, ]) @php // ===== Normalizaciones ===== $align = in_array($align, ['left','center','right'], true) ? $align : 'center'; $sizeMap = ['sm' => 'page-header-sm', 'md' => 'page-header-md', 'lg' => 'page-header-lg']; $sizeClass = $sizeMap[$size] ?? $sizeMap['md']; // ===== Clases base del header ===== $classes = ['page-header','page-header-modern', $sizeClass]; // Modo de fondo $hasBackground = in_array($mode, ['image','fixed','parallax','video','pattern'], true); if ($hasBackground) { $classes[] = 'page-header-background'; if ($mode === 'pattern') { $classes[] = $bgPatternClass; // ej: page-header-background-pattern } } // Overlay $overlayClasses = []; if ($showOverlay) { $overlayClasses = ['overlay', 'overlay-show', "overlay-color-{$overlayColor}", "overlay-op-{$overlayOpacity}"]; } // Color de título $semanticMap = [ 'primary' => 'text-color-primary', 'secondary' => 'text-color-secondary', 'tertiary' => 'text-color-tertiary', 'quaternary' => 'text-color-quaternary', 'dark' => 'text-dark', 'light' => 'text-light', ]; $titleClasses = ['font-weight-bold']; $titleSizeMap = ['sm' => 'text-6', 'md' => 'text-9', 'lg' => 'text-10']; $titleClasses[] = $titleSizeMap[$titleSize] ?? $titleSizeMap['lg']; if ($titleColor === 'auto') { // Heurística: si hay overlay dark -> texto claro; si overlay light -> texto oscuro $titleClasses[] = (in_array($overlayColor, ['dark','primary','secondary','tertiary','quaternary'], true)) ? 'text-light' : 'text-dark'; } elseif (isset($semanticMap[$titleColor])) { $titleClasses[] = $semanticMap[$titleColor]; } elseif (is_string($titleColor) && $titleColor !== '') { $titleClasses[] = $titleColor; // acepta clases crudas } if ($uppercaseTitle) $titleClasses[] = 'text-uppercase'; // Breadcrumbs $ulClasses = ['breadcrumb','d-block']; $ulClasses[] = match ($align) { 'left' => 'text-md-start', 'right' => 'text-md-end', default => 'text-center', }; // Breadcrumb light/dark: auto si null if ($breadcrumbLight === null) { $isDarkishOverlay = in_array($overlayColor, ['dark','primary','secondary','tertiary','quaternary'], true); if ($isDarkishOverlay && $showOverlay) $ulClasses[] = 'breadcrumb-light'; } elseif ($breadcrumbLight === true) { $ulClasses[] = 'breadcrumb-light'; } // Columnas $titleCol = 'col-sm-12 col-md-'.($slot('media')->isNotEmpty() ? '5' : '12'); $mediaCol = 'col-sm-12 col-md-7 d-flex align-items-end justify-content-end'; if ($align === 'left') { $titleWrap = 'order-2 order-sm-1 align-self-center p-static'; $crumbWrap = 'order-1'; } elseif ($align === 'right') { $titleWrap = 'order-2 order-sm-2 align-self-center p-static text-end'; $crumbWrap = 'order-1 text-md-start'; } else { // center $titleWrap = 'align-self-center p-static order-2 text-center'; $crumbWrap = 'order-1'; } // Helpers de animación -> atributos data-* $animAttrs = function (?string $name, int $delay = 0, ?string $duration = null) { if (!$name) return ''; $out = 'appear-animation'; $out .= '" data-appear-animation="'.$name.'"'; if ($delay > 0) $out .= ' data-appear-animation-delay="'.$delay.'"'; if ($duration) $out .= ' data-appear-animation-duration="'.$duration.'"'; return $out; }; @endphp
{{-- Breadcrumbs fila superior (centrado/izq/der según align) --}}
@if($overflowBreadcrumb)
@endif
    @foreach ($breadcrumbs as $breadcrumb) @php $name = $breadcrumb['name'] ?? ''; $active = (bool)($breadcrumb['active'] ?? false); $route = $breadcrumb['route'] ?? null; $params = $breadcrumb['params'] ?? []; $href = $breadcrumb['href'] ?? null; $routeExists = $route && \Illuminate\Support\Facades\Route::has($route); $url = $routeExists ? route($route, $params) : ($href ?: null); @endphp
  • @if (!$active && $url) {{ $name }} @else {{ $name }} @endif
  • @endforeach
@if($overflowBreadcrumb)
@endif
{{-- Columna de título + subtítulo + CTA --}}
@if($overflowTitle)
@endif

{!! $title !!}

@if($overflowTitle)
@endif @if(!empty($subtitle)) @if($overflowSubtitle)
@endif {!! $subtitle !!} @if($overflowSubtitle)
@endif @endif @if(trim($slot('cta')))
{{ $slot('cta') }}
@endif
{{-- Columna media opcional --}} @if(trim($slot('media')))
{{ $slot('media') }}
@endif