fancytextstuff/components/EnhancedTextInput.jsx

140 lines
4.4 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useRef, useState } from "react";
import { motion } from "framer-motion";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Type, X, Sparkles, Shuffle } from "lucide-react";
export default function EnhancedTextInput({
text: _text,
inputText,
onChange: _onChange,
onTextChange,
placeholder,
onRandomFont,
}) {
const text = _text ?? inputText ?? "";
const change = _onChange ?? onTextChange ?? (() => {});
const safeLen = (v) => (typeof v === "string" ? v.length : 0);
const inputRef = useRef(null);
const [focused, setFocused] = useState(false);
const quickTexts = [
"Hello Instagram! 👋",
"Follow me! ✨",
"New Post 🔥",
"Story Time 📖",
"Good Vibes Only ✌️",
];
const handleClear = () => {
change("");
inputRef.current?.focus();
};
const handleQuickText = (qt) => {
change(qt);
inputRef.current?.focus();
};
return (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.2 }}
className="mb-6 sm:mb-8"
>
{/* Stylischer Button über dem Textfeld */}
<div className="flex justify-start mb-4">
<Button
onClick={onRandomFont}
className="bg-pink-600 hover:bg-pink-700 text-white text-sm font-semibold px-4 py-2 rounded-xl shadow-md flex items-center gap-2 transition-all duration-200 hover:scale-105"
>
<Shuffle className="w-4 h-4" />
Try Random Font
</Button>
</div>
{/* Eingabe */}
<div className="relative mb-4">
<div
className={`relative bg-white/95 backdrop-blur-sm rounded-2xl transition-all duration-300 ${
focused
? "ring-2 ring-pink-400 shadow-xl scale-[1.02]"
: "shadow-lg hover:shadow-xl"
}`}
>
<div className="flex items-center p-1">
<div className="flex items-center justify-center w-12 h-12 bg-gradient-to-br from-pink-500 to-purple-600 rounded-xl mr-3">
<Type className="w-5 h-5 text-white" />
</div>
<Input
ref={inputRef}
value={text}
onChange={(e) => change(e.target.value)}
onFocus={() => setFocused(true)}
onBlur={() => setFocused(false)}
placeholder={placeholder}
className="flex-1 border-0 bg-transparent text-gray-800 text-lg font-medium placeholder:text-gray-400 focus-visible:ring-0 focus-visible:ring-offset-0"
maxLength={100}
/>
{!!safeLen(text) && (
<Button
onClick={handleClear}
variant="ghost"
size="sm"
style={{ pointerEvents: "auto" }}
className="mr-2 border border-black/20 hover:border-black/40 hover:bg-black/10 text-black rounded-full w-8 h-8 p-0 transition"
aria-label="Clear text"
>
<X className="w-4 h-4" />
</Button>
)}
</div>
</div>
{/* Counter */}
<span className="absolute -bottom-1 right-4 text-xs text-black font-medium">
{safeLen(text)}/100
</span>
</div>
{/* Quick Examples */}
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.4 }}
className="mb-4"
>
<div className="flex items-center gap-2 mb-3">
<Sparkles className="w-4 h-4 text-yellow-300" />
<span className="text-white/80 text-sm font-medium">Quick Examples:</span>
</div>
<div className="flex flex-wrap gap-2">
{quickTexts.map((qt) => (
<Button
key={qt}
onClick={() => handleQuickText(qt)}
variant="outline"
size="sm"
className="bg-white/10 border-white/20 text-white hover:bg-white/20 backdrop-blur-sm text-xs transition-all duration-200 hover:scale-105"
>
{qt}
</Button>
))}
</div>
</motion.div>
{/* USP / SEO-Text */}
<div className="text-sm text-white/80 text-center space-y-1 mt-6">
<p>📱 Optimized for Instagram, TikTok, Threads & WhatsApp</p>
<p>🔍 SEO-safe Unicode 100% copy-paste ready</p>
<p>🚀 Built for speed & mobile-first UX</p>
</div>
</motion.div>
);
}