UNPKG

anicompo

Version:

A collection of beautiful React components with advanced glass morphism effects and Framer Motion animations

1,693 lines (1,666 loc) 181 kB
'use strict'; var React = require('react'); var framerMotion = require('framer-motion'); var jsxRuntime = require('react/jsx-runtime'); const LiquidGlassButton = ({ children = "Button", onClick, variant = "primary", size = "medium", disabled = false, className = "", style = {}, ...props }) => { const buttonRef = React.useRef(null); const [mousePosition, setMousePosition] = React.useState({ x: 0, y: 0 }); const [isPressed, setIsPressed] = React.useState(false); // Motion values for parallax effect const mouseX = framerMotion.useMotionValue(0); const mouseY = framerMotion.useMotionValue(0); // Transform mouse position to rotation and translation const rotateX = framerMotion.useTransform(mouseY, [-100, 100], [15, -15]); const rotateY = framerMotion.useTransform(mouseX, [-100, 100], [-15, 15]); const translateZ = framerMotion.useTransform(mouseX, [-100, 100], [-10, 10]); // Spring animations for smooth transitions const springConfig = { damping: 15, stiffness: 150 }; const springRotateX = framerMotion.useSpring(rotateX, springConfig); const springRotateY = framerMotion.useSpring(rotateY, springConfig); const springTranslateZ = framerMotion.useSpring(translateZ, springConfig); // Handle mouse movement for parallax effect React.useEffect(() => { const handleMouseMove = e => { if (!buttonRef.current) return; const rect = buttonRef.current.getBoundingClientRect(); const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2; const x = e.clientX - centerX; const y = e.clientY - centerY; mouseX.set(x); mouseY.set(y); setMousePosition({ x, y }); }; const handleMouseLeave = () => { mouseX.set(0); mouseY.set(0); setMousePosition({ x: 0, y: 0 }); }; const button = buttonRef.current; if (button) { button.addEventListener('mousemove', handleMouseMove); button.addEventListener('mouseleave', handleMouseLeave); } return () => { if (button) { button.removeEventListener('mousemove', handleMouseMove); button.removeEventListener('mouseleave', handleMouseLeave); } }; }, [mouseX, mouseY]); // Variant styles const variants = { primary: { background: ` linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 50%, rgba(255, 255, 255, 0.1) 100% ), radial-gradient( circle at 30% 30%, rgba(255, 255, 255, 0.2) 0%, transparent 50% ) `, borderColor: 'rgba(255, 255, 255, 0.3)', color: 'rgba(255, 255, 255, 0.9)', shadowColor: 'rgba(0, 123, 255, 0.3)' }, secondary: { background: ` linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.03) 50%, rgba(255, 255, 255, 0.08) 100% ), radial-gradient( circle at 70% 70%, rgba(255, 255, 255, 0.15) 0%, transparent 50% ) `, borderColor: 'rgba(255, 255, 255, 0.2)', color: 'rgba(255, 255, 255, 0.8)', shadowColor: 'rgba(255, 255, 255, 0.2)' }, success: { background: ` linear-gradient(135deg, rgba(40, 167, 69, 0.1) 0%, rgba(40, 167, 69, 0.05) 50%, rgba(40, 167, 69, 0.1) 100% ), radial-gradient( circle at 30% 30%, rgba(40, 167, 69, 0.2) 0%, transparent 50% ) `, borderColor: 'rgba(40, 167, 69, 0.3)', color: 'rgba(255, 255, 255, 0.9)', shadowColor: 'rgba(40, 167, 69, 0.3)' }, danger: { background: ` linear-gradient(135deg, rgba(220, 53, 69, 0.1) 0%, rgba(220, 53, 69, 0.05) 50%, rgba(220, 53, 69, 0.1) 100% ), radial-gradient( circle at 70% 70%, rgba(220, 53, 69, 0.2) 0%, transparent 50% ) `, borderColor: 'rgba(220, 53, 69, 0.3)', color: 'rgba(255, 255, 255, 0.9)', shadowColor: 'rgba(220, 53, 69, 0.3)' } }; // Size styles const sizes = { small: { padding: '8px 16px', fontSize: '14px', borderRadius: '8px', minHeight: '32px' }, medium: { padding: '12px 24px', fontSize: '16px', borderRadius: '12px', minHeight: '44px' }, large: { padding: '16px 32px', fontSize: '18px', borderRadius: '16px', minHeight: '56px' } }; const currentVariant = variants[variant] || variants.primary; const currentSize = sizes[size] || sizes.medium; return /*#__PURE__*/jsxRuntime.jsxs(framerMotion.motion.button, { ref: buttonRef, onClick: onClick, disabled: disabled, className: `liquid-glass-button ${className}`, style: { position: 'relative', border: `1px solid ${currentVariant.borderColor}`, borderRadius: currentSize.borderRadius, padding: currentSize.padding, fontSize: currentSize.fontSize, minHeight: currentSize.minHeight, color: currentVariant.color, background: currentVariant.background, backdropFilter: 'blur(20px)', WebkitBackdropFilter: 'blur(20px)', backgroundBlendMode: 'overlay', mixBlendMode: 'normal', cursor: disabled ? 'not-allowed' : 'pointer', outline: 'none', transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)', transformStyle: 'preserve-3d', perspective: '1000px', ...style }, whileHover: { scale: disabled ? 1 : 1.02, boxShadow: disabled ? 'none' : ` 0 20px 40px rgba(0, 0, 0, 0.3), 0 0 20px ${currentVariant.shadowColor}, inset 0 1px 0 rgba(255, 255, 255, 0.2) `, filter: disabled ? 'none' : 'brightness(1.1)', transition: { duration: 0.2 } }, whileTap: { scale: disabled ? 1 : 0.98, boxShadow: disabled ? 'none' : ` 0 10px 20px rgba(0, 0, 0, 0.4), inset 0 2px 4px rgba(0, 0, 0, 0.1) `, transition: { duration: 0.1 } }, animate: { rotateX: disabled ? 0 : springRotateX, rotateY: disabled ? 0 : springRotateY, translateZ: disabled ? 0 : springTranslateZ }, onMouseDown: () => !disabled && setIsPressed(true), onMouseUp: () => setIsPressed(false), onMouseLeave: () => setIsPressed(false), ...props, children: [/*#__PURE__*/jsxRuntime.jsx(framerMotion.motion.div, { style: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, background: ` linear-gradient( 135deg, rgba(255, 255, 255, 0.1) 0%, transparent 50%, rgba(255, 255, 255, 0.05) 100% ) `, borderRadius: 'inherit', pointerEvents: 'none', mixBlendMode: 'overlay' }, animate: { opacity: isPressed ? 0.3 : 0.6, scale: isPressed ? 0.95 : 1 }, transition: { duration: 0.2 } }), /*#__PURE__*/jsxRuntime.jsx(framerMotion.motion.div, { style: { position: 'absolute', top: '2px', left: '2px', right: '2px', bottom: '2px', background: ` radial-gradient( circle at 50% 0%, rgba(255, 255, 255, 0.1) 0%, transparent 70% ) `, borderRadius: 'inherit', pointerEvents: 'none', filter: 'blur(1px)' }, animate: { opacity: isPressed ? 0.1 : 0.3 }, transition: { duration: 0.2 } }), /*#__PURE__*/jsxRuntime.jsx(framerMotion.motion.span, { style: { position: 'relative', zIndex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '8px', fontWeight: 500, letterSpacing: '0.5px', textShadow: '0 1px 2px rgba(0, 0, 0, 0.3)' }, animate: { y: isPressed ? 1 : 0 }, transition: { duration: 0.1 }, children: children }), /*#__PURE__*/jsxRuntime.jsx(framerMotion.motion.div, { style: { position: 'absolute', top: '50%', left: '50%', width: 0, height: 0, borderRadius: '50%', background: 'rgba(255, 255, 255, 0.3)', transform: 'translate(-50%, -50%)', pointerEvents: 'none' }, initial: { scale: 0, opacity: 0 }, animate: { scale: isPressed ? 2 : 0, opacity: isPressed ? 0 : 0 }, transition: { duration: 0.6, ease: 'easeOut' } })] }); }; const ButtonDemo = () => { const [clickCount, setClickCount] = React.useState(0); const [isLoading, setIsLoading] = React.useState(false); const handleClick = () => { setClickCount(prev => prev + 1); }; const handleAsyncClick = async () => { setIsLoading(true); await new Promise(resolve => setTimeout(resolve, 2000)); setIsLoading(false); setClickCount(prev => prev + 1); }; return /*#__PURE__*/jsxRuntime.jsxs("div", { style: { minHeight: '100vh', background: ` linear-gradient(135deg, #667eea 0%, #764ba2 100%), radial-gradient(circle at 20% 80%, #f093fb 0%, transparent 50%), radial-gradient(circle at 80% 20%, #f5576c 0%, transparent 50%), radial-gradient(circle at 40% 40%, #4facfe 0%, transparent 50%) `, backgroundBlendMode: 'overlay, screen, screen, screen', padding: '40px 20px', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '40px', fontFamily: 'system-ui, -apple-system, sans-serif' }, children: [/*#__PURE__*/jsxRuntime.jsxs(framerMotion.motion.div, { initial: { opacity: 0, y: -50 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.8 }, style: { textAlign: 'center', color: 'white', marginBottom: '20px' }, children: [/*#__PURE__*/jsxRuntime.jsx("h1", { style: { fontSize: '3rem', fontWeight: 'bold', margin: '0 0 10px 0', textShadow: '0 4px 8px rgba(0, 0, 0, 0.3)', background: 'linear-gradient(45deg, #fff, #f0f0f0)', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent', backgroundClip: 'text' }, children: "Liquid Glass Button" }), /*#__PURE__*/jsxRuntime.jsx("p", { style: { fontSize: '1.2rem', opacity: 0.9, margin: '0', textShadow: '0 2px 4px rgba(0, 0, 0, 0.3)' }, children: "Advanced glass morphism with Framer Motion animations" })] }), /*#__PURE__*/jsxRuntime.jsxs(framerMotion.motion.div, { initial: { opacity: 0, y: 30 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.8, delay: 0.2 }, style: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '20px', width: '100%', maxWidth: '800px' }, children: [/*#__PURE__*/jsxRuntime.jsx("h2", { style: { color: 'white', fontSize: '2rem', margin: '0', textShadow: '0 2px 4px rgba(0, 0, 0, 0.3)' }, children: "Button Variants" }), /*#__PURE__*/jsxRuntime.jsxs("div", { style: { display: 'flex', gap: '20px', flexWrap: 'wrap', justifyContent: 'center' }, children: [/*#__PURE__*/jsxRuntime.jsx(LiquidGlassButton, { variant: "primary", onClick: handleClick, children: "Primary" }), /*#__PURE__*/jsxRuntime.jsx(LiquidGlassButton, { variant: "secondary", onClick: handleClick, children: "Secondary" }), /*#__PURE__*/jsxRuntime.jsx(LiquidGlassButton, { variant: "success", onClick: handleClick, children: "Success" }), /*#__PURE__*/jsxRuntime.jsx(LiquidGlassButton, { variant: "danger", onClick: handleClick, children: "Danger" })] })] }), /*#__PURE__*/jsxRuntime.jsxs(framerMotion.motion.div, { initial: { opacity: 0, y: 30 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.8, delay: 0.4 }, style: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '20px', width: '100%', maxWidth: '800px' }, children: [/*#__PURE__*/jsxRuntime.jsx("h2", { style: { color: 'white', fontSize: '2rem', margin: '0', textShadow: '0 2px 4px rgba(0, 0, 0, 0.3)' }, children: "Button Sizes" }), /*#__PURE__*/jsxRuntime.jsxs("div", { style: { display: 'flex', gap: '20px', flexWrap: 'wrap', justifyContent: 'center', alignItems: 'center' }, children: [/*#__PURE__*/jsxRuntime.jsx(LiquidGlassButton, { size: "small", onClick: handleClick, children: "Small" }), /*#__PURE__*/jsxRuntime.jsx(LiquidGlassButton, { size: "medium", onClick: handleClick, children: "Medium" }), /*#__PURE__*/jsxRuntime.jsx(LiquidGlassButton, { size: "large", onClick: handleClick, children: "Large" })] })] }), /*#__PURE__*/jsxRuntime.jsxs(framerMotion.motion.div, { initial: { opacity: 0, y: 30 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.8, delay: 0.6 }, style: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '20px', width: '100%', maxWidth: '800px' }, children: [/*#__PURE__*/jsxRuntime.jsx("h2", { style: { color: 'white', fontSize: '2rem', margin: '0', textShadow: '0 2px 4px rgba(0, 0, 0, 0.3)' }, children: "Interactive Examples" }), /*#__PURE__*/jsxRuntime.jsxs("div", { style: { display: 'flex', gap: '20px', flexWrap: 'wrap', justifyContent: 'center', alignItems: 'center' }, children: [/*#__PURE__*/jsxRuntime.jsxs(LiquidGlassButton, { variant: "primary", onClick: handleClick, style: { minWidth: '150px' }, children: ["Clicked: ", clickCount] }), /*#__PURE__*/jsxRuntime.jsx(LiquidGlassButton, { variant: "success", onClick: handleAsyncClick, disabled: isLoading, style: { minWidth: '150px' }, children: isLoading ? 'Loading...' : 'Async Action' }), /*#__PURE__*/jsxRuntime.jsx(LiquidGlassButton, { variant: "secondary", disabled: true, style: { minWidth: '150px' }, children: "Disabled" })] })] }), /*#__PURE__*/jsxRuntime.jsxs(framerMotion.motion.div, { initial: { opacity: 0, y: 30 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.8, delay: 0.8 }, style: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '20px', width: '100%', maxWidth: '800px' }, children: [/*#__PURE__*/jsxRuntime.jsx("h2", { style: { color: 'white', fontSize: '2rem', margin: '0', textShadow: '0 2px 4px rgba(0, 0, 0, 0.3)' }, children: "Technical Features" }), /*#__PURE__*/jsxRuntime.jsxs("div", { style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '20px', width: '100%' }, children: [/*#__PURE__*/jsxRuntime.jsxs("div", { style: { background: 'rgba(255, 255, 255, 0.1)', backdropFilter: 'blur(10px)', borderRadius: '12px', padding: '20px', border: '1px solid rgba(255, 255, 255, 0.2)' }, children: [/*#__PURE__*/jsxRuntime.jsx("h3", { style: { color: 'white', margin: '0 0 10px 0' }, children: "Glass Effects" }), /*#__PURE__*/jsxRuntime.jsxs("ul", { style: { color: 'white', margin: 0, paddingLeft: '20px' }, children: [/*#__PURE__*/jsxRuntime.jsx("li", { children: "backdrop-filter: blur(20px)" }), /*#__PURE__*/jsxRuntime.jsx("li", { children: "rgba/hsla backgrounds" }), /*#__PURE__*/jsxRuntime.jsx("li", { children: "background-blend-mode" }), /*#__PURE__*/jsxRuntime.jsx("li", { children: "mix-blend-mode effects" }), /*#__PURE__*/jsxRuntime.jsx("li", { children: "Glass borders & shadows" })] })] }), /*#__PURE__*/jsxRuntime.jsxs("div", { style: { background: 'rgba(255, 255, 255, 0.1)', backdropFilter: 'blur(10px)', borderRadius: '12px', padding: '20px', border: '1px solid rgba(255, 255, 255, 0.2)' }, children: [/*#__PURE__*/jsxRuntime.jsx("h3", { style: { color: 'white', margin: '0 0 10px 0' }, children: "Animations" }), /*#__PURE__*/jsxRuntime.jsxs("ul", { style: { color: 'white', margin: 0, paddingLeft: '20px' }, children: [/*#__PURE__*/jsxRuntime.jsx("li", { children: "Framer Motion integration" }), /*#__PURE__*/jsxRuntime.jsx("li", { children: "Parallax mouse tracking" }), /*#__PURE__*/jsxRuntime.jsx("li", { children: "Spring animations" }), /*#__PURE__*/jsxRuntime.jsx("li", { children: "Hover & tap effects" }), /*#__PURE__*/jsxRuntime.jsx("li", { children: "Ripple effects" })] })] }), /*#__PURE__*/jsxRuntime.jsxs("div", { style: { background: 'rgba(255, 255, 255, 0.1)', backdropFilter: 'blur(10px)', borderRadius: '12px', padding: '20px', border: '1px solid rgba(255, 255, 255, 0.2)' }, children: [/*#__PURE__*/jsxRuntime.jsx("h3", { style: { color: 'white', margin: '0 0 10px 0' }, children: "Customization" }), /*#__PURE__*/jsxRuntime.jsxs("ul", { style: { color: 'white', margin: 0, paddingLeft: '20px' }, children: [/*#__PURE__*/jsxRuntime.jsx("li", { children: "Multiple variants" }), /*#__PURE__*/jsxRuntime.jsx("li", { children: "Size options" }), /*#__PURE__*/jsxRuntime.jsx("li", { children: "Disabled states" }), /*#__PURE__*/jsxRuntime.jsx("li", { children: "Custom styling" }), /*#__PURE__*/jsxRuntime.jsx("li", { children: "Accessible design" })] })] })] })] })] }); }; const LiquidGlassInput = /*#__PURE__*/React.forwardRef(({ type = "text", placeholder = "Enter text...", value = "", onChange, onFocus, onBlur, variant = "primary", size = "medium", disabled = false, error = false, success = false, label = "", helperText = "", required = false, className = "", style = {}, ...props }, ref) => { const inputRef = React.useRef(null); const [isFocused, setIsFocused] = React.useState(false); const [isFilled, setIsFilled] = React.useState(!!value); const [mousePosition, setMousePosition] = React.useState({ x: 0, y: 0 }); // Motion values for parallax effect const mouseX = framerMotion.useMotionValue(0); const mouseY = framerMotion.useMotionValue(0); // Transform mouse position to subtle rotation and translation const rotateX = framerMotion.useTransform(mouseY, [-100, 100], [5, -5]); const rotateY = framerMotion.useTransform(mouseX, [-100, 100], [-5, 5]); const translateZ = framerMotion.useTransform(mouseX, [-100, 100], [-5, 5]); // Spring animations for smooth transitions const springConfig = { damping: 20, stiffness: 200 }; const springRotateX = framerMotion.useSpring(rotateX, springConfig); const springRotateY = framerMotion.useSpring(rotateY, springConfig); const springTranslateZ = framerMotion.useSpring(translateZ, springConfig); // Handle mouse movement for parallax effect React.useEffect(() => { const handleMouseMove = e => { if (!inputRef.current || disabled) return; const rect = inputRef.current.getBoundingClientRect(); const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2; const x = e.clientX - centerX; const y = e.clientY - centerY; mouseX.set(x); mouseY.set(y); setMousePosition({ x, y }); }; const handleMouseLeave = () => { mouseX.set(0); mouseY.set(0); setMousePosition({ x: 0, y: 0 }); }; const input = inputRef.current; if (input) { input.addEventListener('mousemove', handleMouseMove); input.addEventListener('mouseleave', handleMouseLeave); } return () => { if (input) { input.removeEventListener('mousemove', handleMouseMove); input.removeEventListener('mouseleave', handleMouseLeave); } }; }, [mouseX, mouseY, disabled]); // Update filled state when value changes React.useEffect(() => { setIsFilled(!!value); }, [value]); // Variant styles const variants = { primary: { background: ` linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.03) 50%, rgba(255, 255, 255, 0.08) 100% ), radial-gradient( circle at 30% 30%, rgba(255, 255, 255, 0.1) 0%, transparent 50% ) `, borderColor: 'rgba(255, 255, 255, 0.3)', focusBorderColor: 'rgba(0, 123, 255, 0.6)', color: 'rgba(255, 255, 255, 0.9)', placeholderColor: 'rgba(255, 255, 255, 0.5)', shadowColor: 'rgba(0, 123, 255, 0.2)' }, secondary: { background: ` linear-gradient(135deg, rgba(255, 255, 255, 0.06) 0%, rgba(255, 255, 255, 0.02) 50%, rgba(255, 255, 255, 0.06) 100% ), radial-gradient( circle at 70% 70%, rgba(255, 255, 255, 0.08) 0%, transparent 50% ) `, borderColor: 'rgba(255, 255, 255, 0.2)', focusBorderColor: 'rgba(255, 255, 255, 0.5)', color: 'rgba(255, 255, 255, 0.8)', placeholderColor: 'rgba(255, 255, 255, 0.4)', shadowColor: 'rgba(255, 255, 255, 0.15)' }, success: { background: ` linear-gradient(135deg, rgba(40, 167, 69, 0.08) 0%, rgba(40, 167, 69, 0.03) 50%, rgba(40, 167, 69, 0.08) 100% ), radial-gradient( circle at 30% 30%, rgba(40, 167, 69, 0.1) 0%, transparent 50% ) `, borderColor: 'rgba(40, 167, 69, 0.3)', focusBorderColor: 'rgba(40, 167, 69, 0.6)', color: 'rgba(255, 255, 255, 0.9)', placeholderColor: 'rgba(255, 255, 255, 0.5)', shadowColor: 'rgba(40, 167, 69, 0.2)' }, danger: { background: ` linear-gradient(135deg, rgba(220, 53, 69, 0.08) 0%, rgba(220, 53, 69, 0.03) 50%, rgba(220, 53, 69, 0.08) 100% ), radial-gradient( circle at 70% 70%, rgba(220, 53, 69, 0.1) 0%, transparent 50% ) `, borderColor: 'rgba(220, 53, 69, 0.3)', focusBorderColor: 'rgba(220, 53, 69, 0.6)', color: 'rgba(255, 255, 255, 0.9)', placeholderColor: 'rgba(255, 255, 255, 0.5)', shadowColor: 'rgba(220, 53, 69, 0.2)' } }; // Size styles const sizes = { small: { padding: '8px 12px', fontSize: '14px', borderRadius: '8px', minHeight: '36px', labelFontSize: '12px' }, medium: { padding: '12px 16px', fontSize: '16px', borderRadius: '12px', minHeight: '48px', labelFontSize: '14px' }, large: { padding: '16px 20px', fontSize: '18px', borderRadius: '16px', minHeight: '56px', labelFontSize: '16px' } }; const currentVariant = variants[variant] || variants.primary; const currentSize = sizes[size] || sizes.medium; // Determine border color based on state const getBorderColor = () => { if (error) return 'rgba(220, 53, 69, 0.6)'; if (success) return 'rgba(40, 167, 69, 0.6)'; if (isFocused) return currentVariant.focusBorderColor; return currentVariant.borderColor; }; // Determine shadow color based on state const getShadowColor = () => { if (error) return 'rgba(220, 53, 69, 0.3)'; if (success) return 'rgba(40, 167, 69, 0.3)'; return currentVariant.shadowColor; }; const handleFocus = e => { setIsFocused(true); onFocus?.(e); }; const handleBlur = e => { setIsFocused(false); onBlur?.(e); }; const handleChange = e => { setIsFilled(!!e.target.value); onChange?.(e); }; // Custom increment/decrement for number input const isNumber = type === 'number'; const isFullname = type === 'fullname'; const handleStep = step => { if (disabled) return; let newValue = value === '' || value === null ? 0 : Number(value); newValue += step; if (onChange) { // Create a synthetic event to match React's onChange signature const event = { target: { value: String(newValue) } }; onChange(event); } }; // For fullname, value should be { firstname, lastname } const handleFullnameChange = (field, fieldValue) => { if (onChange) { const newValue = { ...value, [field]: fieldValue }; // Create a synthetic event to match React's onChange signature const event = { target: { value: newValue } }; onChange(event); } }; return /*#__PURE__*/jsxRuntime.jsxs(framerMotion.motion.div, { ref: inputRef, className: `liquid-glass-input-container ${className}`, style: { position: 'relative', width: '100%', ...style }, animate: { rotateX: disabled ? 0 : springRotateX, rotateY: disabled ? 0 : springRotateY, translateZ: disabled ? 0 : springTranslateZ }, children: [label && /*#__PURE__*/jsxRuntime.jsxs(framerMotion.motion.label, { style: { display: 'block', fontSize: currentSize.labelFontSize, color: currentVariant.color, marginBottom: '8px', fontWeight: 500, letterSpacing: '0.5px', textShadow: '0 1px 2px rgba(0, 0, 0, 0.3)' }, animate: { y: isFocused || isFilled ? -2 : 0, color: isFocused ? currentVariant.focusBorderColor : currentVariant.color }, transition: { duration: 0.2 }, children: [label, required && /*#__PURE__*/jsxRuntime.jsx("span", { style: { color: 'rgba(220, 53, 69, 0.8)' }, children: " *" })] }), isFullname ? /*#__PURE__*/jsxRuntime.jsxs("div", { style: { display: 'flex', gap: 12 }, children: [/*#__PURE__*/jsxRuntime.jsx(framerMotion.motion.input, { type: "text", value: value?.firstname || '', onChange: e => handleFullnameChange('firstname', e.target.value), placeholder: placeholder?.firstname || 'First name', disabled: disabled, required: required, style: { flex: 1, padding: currentSize.padding, fontSize: currentSize.fontSize, borderRadius: currentSize.borderRadius, background: currentVariant.background, color: currentVariant.color, border: `1px solid ${getBorderColor()}`, outline: 'none', fontWeight: 400, letterSpacing: '0.3px', textShadow: '0 1px 2px rgba(0, 0, 0, 0.3)', boxShadow: '0 2px 8px rgba(0,0,0,0.08)', marginBottom: 0 } }), /*#__PURE__*/jsxRuntime.jsx(framerMotion.motion.input, { type: "text", value: value?.lastname || '', onChange: e => handleFullnameChange('lastname', e.target.value), placeholder: placeholder?.lastname || 'Last name', disabled: disabled, required: required, style: { flex: 1, padding: currentSize.padding, fontSize: currentSize.fontSize, borderRadius: currentSize.borderRadius, background: currentVariant.background, color: currentVariant.color, border: `1px solid ${getBorderColor()}`, outline: 'none', fontWeight: 400, letterSpacing: '0.3px', textShadow: '0 1px 2px rgba(0, 0, 0, 0.3)', boxShadow: '0 2px 8px rgba(0,0,0,0.08)', marginBottom: 0 } })] }) : /*#__PURE__*/ // Input wrapper jsxRuntime.jsxs(framerMotion.motion.div, { style: { position: 'relative', borderRadius: currentSize.borderRadius, background: currentVariant.background, backdropFilter: 'blur(20px)', WebkitBackdropFilter: 'blur(20px)', backgroundBlendMode: 'overlay', border: `1px solid ${getBorderColor()}`, boxShadow: isFocused ? ` 0 10px 30px rgba(0, 0, 0, 0.3), 0 0 15px ${getShadowColor()}, inset 0 1px 0 rgba(255, 255, 255, 0.1) ` : ` 0 4px 16px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.05) `, transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)', transformStyle: 'preserve-3d', perspective: '1000px' }, whileHover: { scale: disabled ? 1 : 1.01, boxShadow: disabled ? undefined : ` 0 8px 24px rgba(0, 0, 0, 0.2), 0 0 12px ${getShadowColor()}, inset 0 1px 0 rgba(255, 255, 255, 0.15) `, transition: { duration: 0.2 } }, animate: { scale: isFocused ? 1.02 : 1, boxShadow: isFocused ? ` 0 15px 40px rgba(0, 0, 0, 0.4), 0 0 20px ${getShadowColor()}, inset 0 1px 0 rgba(255, 255, 255, 0.2) ` : undefined }, transition: { duration: 0.3 }, children: [/*#__PURE__*/jsxRuntime.jsx(framerMotion.motion.div, { style: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, background: ` linear-gradient( 135deg, rgba(255, 255, 255, 0.08) 0%, transparent 50%, rgba(255, 255, 255, 0.03) 100% ) `, borderRadius: 'inherit', pointerEvents: 'none', mixBlendMode: 'overlay' }, animate: { opacity: isFocused ? 0.8 : 0.4 }, transition: { duration: 0.2 } }), /*#__PURE__*/jsxRuntime.jsx(framerMotion.motion.div, { style: { position: 'absolute', top: '2px', left: '2px', right: '2px', bottom: '2px', background: ` radial-gradient( circle at 50% 0%, rgba(255, 255, 255, 0.08) 0%, transparent 70% ) `, borderRadius: 'inherit', pointerEvents: 'none', filter: 'blur(1px)' }, animate: { opacity: isFocused ? 0.4 : 0.2 }, transition: { duration: 0.2 } }), /*#__PURE__*/jsxRuntime.jsx(framerMotion.motion.input, { ref: ref, type: type, value: value, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, disabled: disabled, placeholder: placeholder, required: required, style: { position: 'relative', zIndex: 1, width: '100%', padding: currentSize.padding, fontSize: currentSize.fontSize, minHeight: currentSize.minHeight, color: currentVariant.color, background: 'transparent', border: 'none', outline: 'none', borderRadius: 'inherit', fontWeight: 400, letterSpacing: '0.3px', textShadow: '0 1px 2px rgba(0, 0, 0, 0.3)', cursor: disabled ? 'not-allowed' : 'text', opacity: disabled ? 0.6 : 1, // Add padding right for custom buttons paddingRight: isNumber ? '48px' : currentSize.padding }, animate: { y: isFocused ? 1 : 0 }, transition: { duration: 0.1 }, ...props }), isNumber && !disabled && /*#__PURE__*/jsxRuntime.jsxs("div", { className: "custom-number-arrows", style: { position: 'absolute', right: 8, top: '50%', transform: 'translateY(-50%)', display: 'flex', flexDirection: 'column', gap: 4, zIndex: 2 }, children: [/*#__PURE__*/jsxRuntime.jsx("button", { type: "button", tabIndex: -1, "aria-label": "Increment", onClick: () => handleStep(1), style: { width: 28, height: 24, borderRadius: 8, border: 'none', background: 'linear-gradient(135deg, rgba(255,255,255,0.18) 0%, rgba(255,255,255,0.08) 100%)', boxShadow: '0 2px 8px rgba(0,0,0,0.10)', color: '#fff', fontWeight: 700, fontSize: 18, cursor: 'pointer', marginBottom: 2, display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'background 0.2s', outline: 'none', borderTopLeftRadius: 8, borderTopRightRadius: 8, borderBottomLeftRadius: 0, borderBottomRightRadius: 0, padding: 0 }, children: "\u25B2" }), /*#__PURE__*/jsxRuntime.jsx("button", { type: "button", tabIndex: -1, "aria-label": "Decrement", onClick: () => handleStep(-1), style: { width: 28, height: 24, borderRadius: 8, border: 'none', background: 'linear-gradient(135deg, rgba(255,255,255,0.18) 0%, rgba(255,255,255,0.08) 100%)', boxShadow: '0 2px 8px rgba(0,0,0,0.10)', color: '#fff', fontWeight: 700, fontSize: 18, cursor: 'pointer', marginTop: 2, display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'background 0.2s', outline: 'none', borderTopLeftRadius: 0, borderTopRightRadius: 0, borderBottomLeftRadius: 8, borderBottomRightRadius: 8, padding: 0 }, children: "\u25BC" })] }), /*#__PURE__*/jsxRuntime.jsx("style", { children: ` .liquid-glass-input-container input::placeholder { color: ${currentVariant.placeholderColor}; opacity: 1; transition: color 0.3s ease; } .liquid-glass-input-container input:focus::placeholder { color: ${currentVariant.placeholderColor}80; } .liquid-glass-input-container input:disabled::placeholder { color: ${currentVariant.placeholderColor}40; } /* Hide default number input arrows for Webkit */ .liquid-glass-input-container input[type='number']::-webkit-inner-spin-button, .liquid-glass-input-container input[type='number']::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; display: none; } /* Hide default number input arrows for Firefox */ .liquid-glass-input-container input[type='number'] { -moz-appearance: textfield; } /* Show custom arrows only on hover/focus of wrapper */ .liquid-glass-input-container .custom-number-arrows { opacity: 0; pointer-events: none; transition: opacity 0.2s; } .liquid-glass-input-container:hover .custom-number-arrows, .liquid-glass-input-container:focus-within .custom-number-arrows { opacity: 1; pointer-events: auto; } ` }), error && /*#__PURE__*/jsxRuntime.jsx(framerMotion.motion.div, { initial: { scale: 0, opacity: 0 }, animate: { scale: 1, opacity: 1 }, style: { position: 'absolute', right: '12px', top: '50%', transform: 'translateY(-50%)', width: '8px', height: '8px', borderRadius: '50%', background: 'rgba(220, 53, 69, 0.8)', boxShadow: '0 0 8px rgba(220, 53, 69, 0.5)' } }), success && /*#__PURE__*/jsxRuntime.jsx(framerMotion.motion.div, { initial: { scale: 0, opacity: 0 }, animate: { scale: 1, opacity: 1 }, style: { position: 'absolute', right: '12px', top: '50%', transform: 'translateY(-50%)', width: '8px', height: '8px', borderRadius: '50%', background: 'rgba(40, 167, 69, 0.8)', boxShadow: '0 0 8px rgba(40, 167, 69, 0.5)' } }), isFocused && /*#__PURE__*/jsxRuntime.jsx(framerMotion.motion.div, { initial: { scale: 0.8, opacity: 0 }, animate: { scale: 1, opacity: 1 }, style: { position: 'absolute', top: '-2px', left: '-2px', right: '-2px', bottom: '-2px', borderRadius: 'inherit', background: `linear-gradient(45deg, ${getShadowColor()}, transparent)`, zIndex: -1, filter: 'blur(4px)' }, transition: { duration: 0.3 } })] }), helperText && /*#__PURE__*/jsxRuntime.jsx(framerMotion.motion.p, { initial: { opacity: 0, y: -5 }, animate: { opacity: 1, y: 0 }, style: { margin: '8px 0 0 0', fontSize: '12px', color: error ? 'rgba(220, 53, 69, 0.8)' : success ? 'rgba(40, 167, 69, 0.8)' : 'rgba(255, 255, 255, 0.6)', textShadow: '0 1px 2px rgba(0, 0, 0, 0.3)', fontWeight: 400 }, children: helperText })] }); }); LiquidGlassInput.displayName = 'LiquidGlassInput'; const InputDemo = () => { const [formData, setFormData] = React.useState({ fullname: { firstname: '', lastname: '' }, email: '', password: '', message: '', search: '' }); const [errors, setErrors] = React.useState({}); const [success, setSuccess] = React.useState({}); const [specialInputs, setSpecialInputs] = React.useState({ email: '', password: '', number: '', phone: '', fullname: { firstname: '', lastname: '' } }); const handleInputChange = (field, value) => { setFormData(prev => ({ ...prev, [field]: value })); // Clear errors when user starts typing if (errors[field]) { setErrors(prev => ({ ...prev, [field]: '' })); } // Validate email if (field === 'email' && value) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(value)) { setErrors(prev => ({ ...prev, email: 'Please enter a valid email address' })); } else { setSuccess(prev => ({ ...prev, email: true })); } } // Validate password if (field === 'password' && value) { if (value.length < 6) { setErrors(prev => ({ ...prev, password: 'Password must be at least 6 characters' })); } else { setSuccess(prev => ({ ...prev, password: true })); } } }; const handleSpecialInputChange = (field, value) => { setSpecialInputs(prev => ({ ...prev, [field]: value })); }; const handleSubmit = e => { e.preventDefault(); console.log('Form submitted:', formData); }; return /*#__PURE__*/jsxRuntime.jsxs("div", { style: { minHeight: '100vh', background: ` linear-gradient(135deg, #667eea 0%, #764ba2 100%), radial-gradient(circle at 20% 80%, #f093fb 0%, transparent 50%), radial-gradient(circle at 80% 20%, #f5576c 0%, transparent 50%), radial-gradient(circle at 40% 40%, #4facfe 0%, transparent 50%) `, backgroundBlendMode: 'overlay, screen, screen, screen', padding: '40px 20px', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '40px', fontFamily: 'system-ui, -apple-system, sans-serif' }, children: [/*#__PURE__*/jsxRuntime.jsxs(framerMotion.motion.div, { initial: { opacity: 0, y: -50 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.8 }, style: { textAlign: 'center', color: 'white', marginBottom: '20px' }, children: [/*#__PURE__*/jsxRuntime.jsx("h1", { style: { fontSize: '3rem', fontWeight: 'bold', margin: '0 0 10px 0', textShadow: '0 4px 8px rgba(0, 0, 0, 0.3)', background: 'linear-gradient(45deg, #fff, #f0f0f0)', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent', backgroundClip: 'text' }, children: "Liquid Glass Input" }), /*#__PURE__*/jsxRuntime.jsx("p", { style: { fontSize: '1.2rem', opacity: 0.9, margin: '0', textShadow: '0 2px 4px rgba(0, 0, 0, 0.3)' }, children: "Advanced glass morphism input fields with validation" })] }), /*#__PURE__*/jsxRuntime.jsxs(framerMotion.motion.div, { initial: { opacity: 0, y: 30 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.8, delay: 0.2 }, style: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '20px', width: '100%', maxWidth: '800px' }, children: [/*#__PURE__*/jsxRuntime.jsx("h2", { style: { color: 'white', fontSize: '2rem', margin: '0', textShadow: '0 2px 4px rgba(0, 0, 0, 0.3)' }, children: "Input Variants" }), /*#__PURE__*/jsxRuntime.jsxs("div", { style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '20px', width: '100%' }, children: [/*#__PURE__*/jsxRuntime.jsx(LiquidGlassInput, { variant: "primary", label: "Primary Input", placeholder: "Enter your text...", value: formData.fullname.firstname, onChange: e => handleInputChange('fullname', { ...formData.fullname, firstname: e.target.value }) }), /*#__PURE__*/jsxRuntime.jsx(LiquidGlassInput, { variant: "secondary", label: "Secondary Input", placeholder: "Secondary style...", value: formData.search, onChange: e => handleInputChange('search', e.target.value) }), /*#__PURE__*/jsxRuntime.jsx(LiquidGlassInput, { variant: "success", label: "Success Input", placeholder: "Success state...", value: "Valid input", success: true }), /*#__PURE__*/jsxRuntime.jsx(LiquidGlassInput, { variant: "danger", label: "Error Input", placeholder: "Error state...", value: "Invalid input", error: true, helperText: "This field has an error" })] })] }), /*#__PURE__*/jsxRuntime.jsxs(framerMotion.motion.div, { initial: { opacity: 0, y: 30 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.8, delay: 0.4 }, style: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '20px', width: '100%', maxWidth: '800px' }, children: [/*#__PURE__*/jsxRuntime.jsx("h2", { style: { color: 'white', fontSize: '2rem', margin: '0', textShadow: '0 2px 4px rgba(0, 0, 0, 0.3)' }, children: "Input Sizes" }), /*#__PURE__*/jsxRuntime.jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '20px', width: '100%' }, children: [/*#__PURE__*/jsxRuntime.jsx(LiquidGlassInput, { size: "small", label: "Small Input", placeholder: "Small size...", value: formData.search, onChange: e => handleInputChange('search', e.target.value) }), /*#__PURE__*/jsxRuntime.jsx(LiquidGlassInput, { size: "medium", label: "Medium Input (Default)", placeholder: "Medium size...", value: formData.fullname.firstname, onChange: e => handleInputChange('fullname', { ...formData.fullname, firstname: e.target.value }) }), /*#__PURE__*/jsxRuntime.jsx(LiquidGlassInput, { size: "large", label: "Large Input", placeholder: "Large size...", value: formData.message, onChange: e => handleInputChange('message', e.target.value) })] })] }), /*#__PURE__*/jsxRuntime.jsxs(framerMotion.motion.div, { initial: { opacity: 0, y: 30 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.8, delay: 0.6 }, style: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '20px', width: '100%', maxWidth: '800px' }, children: [/*#__PURE__*/jsxRuntime.jsx("h2", { style: { color: 'white', fontSize: '2rem', margin: '0', textShadow: '0 2px 4px rgba(0, 0, 0, 0.3)' }, children: "Interactive Form" }), /*#__PURE__*/jsxRuntime.jsxs(framerMotion.motion.form, { onSubmit: handleSubmit, style: { display: 'flex', flexDirection: 'column', gap: '20px', width: '100%', background: 'rgba(255, 255, 255, 0.1)', backdropFilter: 'blur(20px)', borderRadius: '20px', padding: '30px', border: '1px solid rgba(255, 255, 255, 0.2)' }, whileHover: { boxShadow: '0 20px 40px rgba(0, 0, 0, 0.3)' }, transition: { duration: 0.3 }, children: [/*#__PURE__*/jsxRuntime.jsx(LiquidGlassInput, { type: "fullname", label: "Full Name", placeholder: { firstname: 'First name', lastname: 'Last name' }, value: formData.fullname, onChange: e => handleInputChange('fullname', e.target.value), required: true, helperText: "Please enter your complete name" }), /*#__PURE__*/jsxRuntime.jsx(LiquidGlassInput, { type: "email", label: "Email Address", placeholder: "Enter your email", value: formData.email, onChange: e => handleInputChange('email', e.target.value), error: !!errors.email, success: success.email, helperText: errors.email || (success.email ? 'Email is valid!' : 'We\'ll never share your email'), required: true }), /*#__PURE__*/jsxRuntime.jsx(LiquidGlassInp