fix hero btn and navigate on click bar
This commit is contained in:
@@ -2,7 +2,8 @@ import React, { useState, useEffect, useCallback } from 'react';
|
|||||||
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
||||||
import { navigateTo } from './Router';
|
import { navigateTo } from './Router';
|
||||||
import svgPaths from "../imports/svg-i1joeov37f";
|
import svgPaths from "../imports/svg-i1joeov37f";
|
||||||
|
import PrimaryCTAButton from './PrimaryCTAButton';
|
||||||
|
|
||||||
interface SlideData {
|
interface SlideData {
|
||||||
id: number;
|
id: number;
|
||||||
title: string;
|
title: string;
|
||||||
@@ -11,12 +12,12 @@ interface SlideData {
|
|||||||
ctaText: string;
|
ctaText: string;
|
||||||
route: string;
|
route: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function HeroSection() {
|
export default function HeroSection() {
|
||||||
const [currentSlide, setCurrentSlide] = useState(0);
|
const [currentSlide, setCurrentSlide] = useState(0);
|
||||||
const [isAutoPlaying, setIsAutoPlaying] = useState(true);
|
const [isAutoPlaying, setIsAutoPlaying] = useState(true);
|
||||||
const [progressValues, setProgressValues] = useState([0, 0, 0, 0, 0, 0]);
|
const [progressValues, setProgressValues] = useState([0, 0, 0, 0, 0, 0]);
|
||||||
|
|
||||||
const slides: SlideData[] = [
|
const slides: SlideData[] = [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
@@ -32,7 +33,7 @@ export default function HeroSection() {
|
|||||||
backgroundImage: "https://images.unsplash.com/photo-1705234384669-c6d31c61b789?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxleGVjdXRpdmUlMjBsZWFkZXJzaGlwJTIwZGV2ZWxvcG1lbnQlMjB0cmFpbmluZ3xlbnwxfHx8fDE3NTY4MDcyNjJ8MA&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral",
|
backgroundImage: "https://images.unsplash.com/photo-1705234384669-c6d31c61b789?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxleGVjdXRpdmUlMjBsZWFkZXJzaGlwJTIwZGV2ZWxvcG1lbnQlMjB0cmFpbmluZ3xlbnwxfHx8fDE3NTY4MDcyNjJ8MA&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral",
|
||||||
shortTitle: "Leadership Development",
|
shortTitle: "Leadership Development",
|
||||||
ctaText: "Explore Leadership Journeys",
|
ctaText: "Explore Leadership Journeys",
|
||||||
route: '/services/leadership-development'
|
route: '/services/leadership-development'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
@@ -67,25 +68,25 @@ export default function HeroSection() {
|
|||||||
route: '/services/learning-facility'
|
route: '/services/learning-facility'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const totalSlides = slides.length;
|
const totalSlides = slides.length;
|
||||||
const slideDuration = 5000; // 5 seconds per slide
|
const slideDuration = 5000; // 5 seconds per slide
|
||||||
|
|
||||||
// Auto-advance slides
|
// Auto-advance slides
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isAutoPlaying) return;
|
if (!isAutoPlaying) return;
|
||||||
|
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
setCurrentSlide((prev) => (prev + 1) % totalSlides);
|
setCurrentSlide((prev) => (prev + 1) % totalSlides);
|
||||||
}, slideDuration);
|
}, slideDuration);
|
||||||
|
|
||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, [isAutoPlaying, totalSlides]);
|
}, [isAutoPlaying, totalSlides]);
|
||||||
|
|
||||||
// Progress bar animation
|
// Progress bar animation
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isAutoPlaying) return;
|
if (!isAutoPlaying) return;
|
||||||
|
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
setProgressValues(prev => {
|
setProgressValues(prev => {
|
||||||
const newProgress = [...prev];
|
const newProgress = [...prev];
|
||||||
@@ -103,10 +104,10 @@ export default function HeroSection() {
|
|||||||
return newProgress;
|
return newProgress;
|
||||||
});
|
});
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, [currentSlide, isAutoPlaying]);
|
}, [currentSlide, isAutoPlaying]);
|
||||||
|
|
||||||
// Reset progress when manually changing slides
|
// Reset progress when manually changing slides
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setProgressValues(prev => {
|
setProgressValues(prev => {
|
||||||
@@ -115,7 +116,7 @@ export default function HeroSection() {
|
|||||||
return newProgress;
|
return newProgress;
|
||||||
});
|
});
|
||||||
}, [currentSlide]);
|
}, [currentSlide]);
|
||||||
|
|
||||||
const goToSlide = useCallback((slideIndex: number) => {
|
const goToSlide = useCallback((slideIndex: number) => {
|
||||||
if (slideIndex !== currentSlide) {
|
if (slideIndex !== currentSlide) {
|
||||||
setCurrentSlide(slideIndex);
|
setCurrentSlide(slideIndex);
|
||||||
@@ -124,23 +125,23 @@ export default function HeroSection() {
|
|||||||
setTimeout(() => setIsAutoPlaying(true), 3000);
|
setTimeout(() => setIsAutoPlaying(true), 3000);
|
||||||
}
|
}
|
||||||
}, [currentSlide]);
|
}, [currentSlide]);
|
||||||
|
|
||||||
const nextSlide = useCallback(() => {
|
const nextSlide = useCallback(() => {
|
||||||
const next = (currentSlide + 1) % totalSlides;
|
const next = (currentSlide + 1) % totalSlides;
|
||||||
goToSlide(next);
|
goToSlide(next);
|
||||||
}, [currentSlide, totalSlides, goToSlide]);
|
}, [currentSlide, totalSlides, goToSlide]);
|
||||||
|
|
||||||
const prevSlide = useCallback(() => {
|
const prevSlide = useCallback(() => {
|
||||||
const prev = (currentSlide - 1 + totalSlides) % totalSlides;
|
const prev = (currentSlide - 1 + totalSlides) % totalSlides;
|
||||||
goToSlide(prev);
|
goToSlide(prev);
|
||||||
}, [currentSlide, totalSlides, goToSlide]);
|
}, [currentSlide, totalSlides, goToSlide]);
|
||||||
|
|
||||||
// Pause auto-play on hover
|
// Pause auto-play on hover
|
||||||
const handleMouseEnter = () => setIsAutoPlaying(false);
|
const handleMouseEnter = () => setIsAutoPlaying(false);
|
||||||
const handleMouseLeave = () => setIsAutoPlaying(true);
|
const handleMouseLeave = () => setIsAutoPlaying(true);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section
|
<section
|
||||||
className="hero-section"
|
className="hero-section"
|
||||||
onMouseEnter={handleMouseEnter}
|
onMouseEnter={handleMouseEnter}
|
||||||
onMouseLeave={handleMouseLeave}
|
onMouseLeave={handleMouseLeave}
|
||||||
@@ -157,7 +158,7 @@ export default function HeroSection() {
|
|||||||
<div className="hero-overlay" />
|
<div className="hero-overlay" />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{/* Hero Content */}
|
{/* Hero Content */}
|
||||||
<div className="hero-content">
|
<div className="hero-content">
|
||||||
<div className="hero-text-section">
|
<div className="hero-text-section">
|
||||||
@@ -167,144 +168,54 @@ export default function HeroSection() {
|
|||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
{/* Dynamic CTA Button - Enhanced with Proper Navigation */}
|
{/* Dynamic CTA Button - Enhanced with Proper Navigation */}
|
||||||
<button
|
|
||||||
className="hero-slide-button group box-border content-stretch flex flex-row gap-2.5 items-center justify-start p-0 relative cursor-pointer overflow-hidden"
|
|
||||||
style={{
|
|
||||||
background: 'transparent',
|
|
||||||
border: 'none'
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
console.log('Hero button clicked - navigating to contact page');
|
|
||||||
navigateTo(slides[currentSlide].route);
|
|
||||||
}}
|
|
||||||
aria-label={slides[currentSlide].ctaText}
|
|
||||||
>
|
|
||||||
{/* Icon Container with Slide Animation */}
|
|
||||||
<div className="relative shrink-0 size-[50px] overflow-hidden">
|
|
||||||
{/* Background Rectangle - Consistent Blue Color */}
|
|
||||||
<div className="absolute inset-0 bg-[#04045B]" />
|
|
||||||
|
|
||||||
{/* Icon Layer - Sliding Animation */}
|
|
||||||
<div className="icon-layer absolute inset-0 w-full h-full">
|
|
||||||
{/* Primary Arrow - Slides out diagonally up-right */}
|
|
||||||
<div className="icon absolute inset-0 flex items-center justify-center transition-all duration-300 ease-in-out group-hover:translate-x-6 group-hover:-translate-y-6 group-hover:opacity-0">
|
|
||||||
<svg
|
|
||||||
className="block w-full h-full"
|
|
||||||
fill="none"
|
|
||||||
preserveAspectRatio="none"
|
|
||||||
viewBox="0 0 50 50"
|
|
||||||
>
|
|
||||||
<g clipPath="url(#clip0_95_1043_primary)">
|
|
||||||
<path d={svgPaths.p5b8d700} fill="white" />
|
|
||||||
<path d={svgPaths.p30b71a00} fill="white" />
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_95_1043_primary">
|
|
||||||
<rect fill="white" height="50" width="50" />
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Secondary Arrow - Slides in from bottom-left */}
|
|
||||||
<div className="icon absolute inset-0 flex items-center justify-center opacity-0 -translate-x-6 translate-y-6 transition-all duration-300 ease-in-out group-hover:translate-x-0 group-hover:translate-y-0 group-hover:opacity-100">
|
|
||||||
<svg
|
|
||||||
className="block w-full h-full"
|
|
||||||
fill="none"
|
|
||||||
preserveAspectRatio="none"
|
|
||||||
viewBox="0 0 50 50"
|
|
||||||
>
|
|
||||||
<g clipPath="url(#clip0_95_1043_secondary)">
|
|
||||||
<path d={svgPaths.p5b8d700} fill="white" />
|
|
||||||
<path d={svgPaths.p30b71a00} fill="white" />
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_95_1043_secondary">
|
|
||||||
<rect fill="white" height="50" width="50" />
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Text Section with Vertical Slide Animation */}
|
<PrimaryCTAButton
|
||||||
<div className="text-layer relative shrink-0 overflow-hidden flex items-center" style={{
|
text={slides[currentSlide].ctaText}
|
||||||
height: '28px',
|
onClick={() => navigateTo(slides[currentSlide].route)}
|
||||||
fontFamily: 'Inter, sans-serif',
|
ariaLabel="Learn more about KLC"
|
||||||
fontSize: '20px',
|
/>
|
||||||
fontWeight: '400',
|
|
||||||
lineHeight: '28px',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
color: '#ffffff'
|
|
||||||
}}>
|
|
||||||
{/* Primary Text - Slides up and out */}
|
|
||||||
<div
|
|
||||||
className="text-element absolute inset-0 flex items-center justify-start transition-all duration-300 ease-in-out group-hover:-translate-y-full group-hover:opacity-0"
|
|
||||||
style={{
|
|
||||||
color: '#ffffff !important',
|
|
||||||
textShadow: '0 1px 2px rgba(0, 0, 0, 0.4)',
|
|
||||||
fontFamily: 'Inter, sans-serif',
|
|
||||||
fontSize: '20px',
|
|
||||||
fontWeight: '400',
|
|
||||||
lineHeight: '28px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{slides[currentSlide].ctaText}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Secondary Text - Slides in from bottom */}
|
|
||||||
<div
|
|
||||||
className="text-element absolute inset-0 flex items-center justify-start translate-y-full opacity-0 transition-all duration-300 ease-in-out group-hover:translate-y-0 group-hover:opacity-100"
|
|
||||||
style={{
|
|
||||||
color: '#ffffff !important',
|
|
||||||
textShadow: '0 1px 2px rgba(0, 0, 0, 0.4)',
|
|
||||||
fontFamily: 'Inter, sans-serif',
|
|
||||||
fontSize: '20px',
|
|
||||||
fontWeight: '400',
|
|
||||||
lineHeight: '28px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{slides[currentSlide].ctaText}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{/* Bottom Navigation */}
|
{/* Bottom Navigation */}
|
||||||
<div className="hero-navigation">
|
<div className="hero-navigation">
|
||||||
{/* Progress Section */}
|
{/* Progress Section */}
|
||||||
<div className="hero-progress-container">
|
<div className="hero-progress-container">
|
||||||
{slides.map((slide, index) => (
|
{slides.map((slide, index) => (
|
||||||
<div
|
<div
|
||||||
key={slide.id}
|
key={slide.id}
|
||||||
className="hero-progress-item"
|
className="hero-progress-item"
|
||||||
onClick={() => goToSlide(index)}
|
onClick={() => goToSlide(index)}
|
||||||
>
|
>
|
||||||
{/* Progress Bar */}
|
{/* Progress Bar */}
|
||||||
<div
|
<div
|
||||||
className={`hero-progress-segment ${index === currentSlide ? 'active' : ''}`}
|
key={slide.id}
|
||||||
|
className="hero-progress-item"
|
||||||
|
onClick={() => navigateTo(slide.route)}
|
||||||
>
|
>
|
||||||
<div
|
{/* Progress Bar */}
|
||||||
className="hero-progress-fill"
|
<div className={`hero-progress-segment ${index === currentSlide ? 'active' : ''}`}>
|
||||||
style={{ width: index === currentSlide ? `${progressValues[index]}%` : '0%' }}
|
<div
|
||||||
/>
|
className="hero-progress-fill"
|
||||||
</div>
|
style={{ width: index === currentSlide ? `${progressValues[index]}%` : '0%' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Progress Number */}
|
{/* Progress Number */}
|
||||||
<div className={`hero-progress-number ${index === currentSlide ? 'active' : ''}`}>
|
<div className={`hero-progress-number ${index === currentSlide ? 'active' : ''}`}>
|
||||||
{String(index + 1).padStart(2, '0')}
|
{String(index + 1).padStart(2, '0')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Progress Text */}
|
{/* Progress Text */}
|
||||||
<div className={`hero-progress-text ${index === currentSlide ? 'active' : ''}`}>
|
<div className={`hero-progress-text ${index === currentSlide ? 'active' : ''}`}>
|
||||||
{slide.shortTitle}
|
{slide.shortTitle}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Navigation Arrows */}
|
{/* Navigation Arrows */}
|
||||||
<div className="hero-controls">
|
<div className="hero-controls">
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -1,146 +1,101 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useState } from 'react';
|
||||||
import svgPaths from "../imports/svg-i1joeov37f";
|
import { ArrowRight } from 'lucide-react';
|
||||||
import { navigateTo } from './Router';
|
|
||||||
|
|
||||||
interface PrimaryCTAButtonProps {
|
interface PrimaryCTAButtonProps {
|
||||||
text: string;
|
text: string;
|
||||||
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
onClick: () => void;
|
||||||
className?: string;
|
|
||||||
ariaLabel?: string;
|
ariaLabel?: string;
|
||||||
debugId?: string; // Add debug identifier
|
className?: string;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PrimaryCTAButton: React.FC<PrimaryCTAButtonProps> = ({
|
export function PrimaryCTAButton({
|
||||||
text,
|
text,
|
||||||
onClick,
|
onClick,
|
||||||
|
ariaLabel,
|
||||||
className = '',
|
className = '',
|
||||||
ariaLabel,
|
disabled = false
|
||||||
debugId = 'unknown'
|
}: PrimaryCTAButtonProps) {
|
||||||
}) => {
|
const [isHovered, setIsHovered] = useState(false);
|
||||||
// Debug: Log when component mounts
|
|
||||||
useEffect(() => {
|
|
||||||
console.log(`PrimaryCTAButton ${debugId} mounted`);
|
|
||||||
}, [debugId]);
|
|
||||||
|
|
||||||
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
|
|
||||||
e.preventDefault();
|
|
||||||
console.log(`Primary CTA Button ${debugId} clicked with text: "${text}"`); // Debug log
|
|
||||||
// Handle webinars navigation
|
|
||||||
if (text === "Join Our Webinars" || text === "Explore Webinars" || text === "View Webinars") {
|
|
||||||
console.log(`Navigating to webinars page for ${debugId}`);
|
|
||||||
navigateTo('/webinars');
|
|
||||||
} else if (text === "Register Free" || text === "Watch Replay" || text === "Launch in Zoom") {
|
|
||||||
// These are handled by individual webinar detail pages
|
|
||||||
console.log(`Webinar CTA handled by detail page for ${debugId}`);
|
|
||||||
} else if (onClick) {
|
|
||||||
console.log(`Custom onClick handler found for ${debugId}, executing it`); // Debug log
|
|
||||||
onClick(e);
|
|
||||||
} else {
|
|
||||||
console.log(`No custom onClick for ${debugId}, navigating to webcast page`); // Debug log
|
|
||||||
// Navigate to webcast page by default
|
|
||||||
navigateTo('/learning/webcast');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
className={`primary-cta-button group box-border content-stretch flex flex-row gap-2.5 items-center justify-start p-0 relative cursor-pointer overflow-hidden ${className}`}
|
onClick={onClick}
|
||||||
style={{
|
disabled={disabled}
|
||||||
background: 'transparent',
|
aria-label={ariaLabel || text}
|
||||||
border: 'none',
|
className={`primary-cta-button ${className}`}
|
||||||
width: 'fit-content' // Perfect width - no extra horizontal space
|
onMouseEnter={() => setIsHovered(true)}
|
||||||
|
onMouseLeave={() => setIsHovered(false)}
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
gap: '12px',
|
||||||
|
padding: '8px 20px',
|
||||||
|
borderRadius: '10px',
|
||||||
|
border: 'none',
|
||||||
|
cursor: disabled ? 'not-allowed' : 'pointer',
|
||||||
|
fontSize: 'var(--font-body-lg)',
|
||||||
|
fontWeight: 'var(--font-weight-h3)',
|
||||||
|
fontFamily: 'var(--font-family-base)',
|
||||||
|
backgroundColor: disabled ? '#9CA3AF' : 'var(--color-primary)',
|
||||||
|
color: '#FFFFFF',
|
||||||
|
boxShadow: disabled
|
||||||
|
? 'none'
|
||||||
|
: '0 4px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06)',
|
||||||
|
transition: 'all 300ms ease-in-out',
|
||||||
|
position: 'relative',
|
||||||
|
overflow: 'hidden',
|
||||||
|
opacity: disabled ? 0.6 : 1,
|
||||||
|
transform: isHovered && !disabled ? 'translateY(-2px)' : 'translateY(0)',
|
||||||
|
...(isHovered && !disabled && {
|
||||||
|
backgroundColor: '#030359', // Darker shade of primary brand color
|
||||||
|
boxShadow: '0 8px 25px rgba(4, 4, 91, 0.3), 0 4px 6px rgba(4, 4, 91, 0.1)'
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Text */}
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
fontSize: 'var(--font-body-lg)',
|
||||||
|
fontWeight: 'var(--font-weight-h3)',
|
||||||
|
fontFamily: 'var(--font-family-base)',
|
||||||
|
color: '#FFFFFF',
|
||||||
|
whiteSpace: 'nowrap'
|
||||||
}}
|
}}
|
||||||
onClick={handleClick}
|
|
||||||
aria-label={ariaLabel || text}
|
|
||||||
>
|
>
|
||||||
{/* Icon Container with Slide Animation */}
|
{text}
|
||||||
<div className="relative shrink-0 size-[50px] overflow-hidden">
|
</span>
|
||||||
{/* Background Rectangle - Consistent Yellow Color */}
|
|
||||||
<div className="absolute inset-0 bg-[#F8C301]" />
|
{/* Arrow icon with enhanced animation */}
|
||||||
|
<span
|
||||||
{/* Icon Layer - Sliding Animation */}
|
style={{
|
||||||
<div className="icon-layer absolute inset-0 w-full h-full">
|
display: 'flex',
|
||||||
{/* Primary Arrow - Slides out diagonally up-right */}
|
alignItems: 'center',
|
||||||
<div className="icon absolute inset-0 flex items-center justify-center transition-all duration-300 ease-in-out group-hover:translate-x-6 group-hover:-translate-y-6 group-hover:opacity-0">
|
justifyContent: 'center',
|
||||||
<svg
|
width: '20px',
|
||||||
className="block w-full h-full"
|
height: '20px',
|
||||||
fill="none"
|
borderRadius: '50%',
|
||||||
preserveAspectRatio="none"
|
backgroundColor: 'rgba(255, 255, 255, 0.2)',
|
||||||
viewBox="0 0 50 50"
|
transition: 'all 300ms ease-in-out',
|
||||||
>
|
transform: isHovered && !disabled ? 'translateX(4px) scale(1.1)' : 'translateX(0) scale(1)',
|
||||||
<g clipPath="url(#clip0_primary_cta_primary)">
|
...(isHovered && !disabled && {
|
||||||
<path d={svgPaths.p5b8d700} fill="white" />
|
backgroundColor: 'rgba(255, 255, 255, 0.3)'
|
||||||
<path d={svgPaths.p30b71a00} fill="white" />
|
})
|
||||||
</g>
|
}}
|
||||||
<defs>
|
>
|
||||||
<clipPath id="clip0_primary_cta_primary">
|
<ArrowRight
|
||||||
<rect fill="white" height="50" width="50" />
|
size={14}
|
||||||
</clipPath>
|
style={{
|
||||||
</defs>
|
color: '#FFFFFF',
|
||||||
</svg>
|
transition: 'all 300ms ease-in-out'
|
||||||
</div>
|
}}
|
||||||
|
/>
|
||||||
{/* Secondary Arrow - Slides in from bottom-left */}
|
</span>
|
||||||
<div className="icon absolute inset-0 flex items-center justify-center opacity-0 -translate-x-6 translate-y-6 transition-all duration-300 ease-in-out group-hover:translate-x-0 group-hover:translate-y-0 group-hover:opacity-100">
|
</button>
|
||||||
<svg
|
|
||||||
className="block w-full h-full"
|
|
||||||
fill="none"
|
|
||||||
preserveAspectRatio="none"
|
|
||||||
viewBox="0 0 50 50"
|
|
||||||
>
|
|
||||||
<g clipPath="url(#clip0_primary_cta_secondary)">
|
|
||||||
<path d={svgPaths.p5b8d700} fill="white" />
|
|
||||||
<path d={svgPaths.p30b71a00} fill="white" />
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_primary_cta_secondary">
|
|
||||||
<rect fill="white" height="50" width="50" />
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Text Section with Vertical Slide Animation */}
|
|
||||||
<div className="text-layer relative shrink-0 overflow-hidden flex items-center" style={{
|
|
||||||
height: '28px',
|
|
||||||
fontFamily: 'Inter, sans-serif',
|
|
||||||
fontSize: '20px',
|
|
||||||
fontWeight: '400',
|
|
||||||
lineHeight: '28px',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
color: '#ffffff',
|
|
||||||
width: 'fit-content' // Perfect text width - no extra horizontal space
|
|
||||||
}}>
|
|
||||||
{/* Primary Text - Slides up and out */}
|
|
||||||
<div
|
|
||||||
className="text-element absolute inset-0 flex items-center justify-start transition-all duration-300 ease-in-out group-hover:-translate-y-full group-hover:opacity-0"
|
|
||||||
style={{
|
|
||||||
color: '#ffffff',
|
|
||||||
fontFamily: 'Inter, sans-serif',
|
|
||||||
fontSize: '20px',
|
|
||||||
fontWeight: '400',
|
|
||||||
lineHeight: '28px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{text}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Secondary Text - Slides in from bottom */}
|
|
||||||
<div
|
|
||||||
className="text-element absolute inset-0 flex items-center justify-start translate-y-full opacity-0 transition-all duration-300 ease-in-out group-hover:translate-y-0 group-hover:opacity-100"
|
|
||||||
style={{
|
|
||||||
color: '#ffffff',
|
|
||||||
fontFamily: 'Inter, sans-serif',
|
|
||||||
fontSize: '20px',
|
|
||||||
fontWeight: '400',
|
|
||||||
lineHeight: '28px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{text}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// Named exports for backward compatibility
|
||||||
|
export const PrimaryCTAButtonProps = PrimaryCTAButton;
|
||||||
|
export default PrimaryCTAButton;
|
||||||
Reference in New Issue
Block a user