Input
ComponentsText input fields.
Default Input
Install this package in your project before importing the animated component.
npm i framer-motion lucide-react <input class="flex h-10 w-full max-w-sm rounded-md border border-input bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2" placeholder="Email" /> <input className="flex h-10 w-full max-w-sm rounded-md border border-input bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2" placeholder="Email" /> "use client";
import React, { useState } from "react";
interface InputDefaultProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
}
export default function InputDefault({
label = "Email Address",
error,
className = "",
...props
}: InputDefaultProps) {
const [value, setValue] = useState("");
const [isFocused, setIsFocused] = useState(false);
return (
<div className="w-full max-w-xs space-y-1.5">
{label && <label className="text-xs font-semibold text-foreground">{label}</label>}
<div className="relative">
<input
{...props}
value={value}
onChange={(e) => setValue(e.target.value)}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
className={`w-full px-3.5 py-2 text-xs rounded-xl border bg-background text-foreground transition-all focus:outline-hidden ${
isFocused
? "border-primary ring-2 ring-primary/20"
: "border-input hover:border-border"
} ${error ? "border-destructive ring-destructive/20" : ""} ${className}`}
placeholder="Enter value..."
/>
{value && (
<button
type="button"
onClick={() => setValue("")}
className="absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground text-xs"
>
✕
</button>
)}
</div>
{error && <p className="text-[11px] text-destructive">{error}</p>}
</div>
);
} "use client";
import React from "react";
import { motion } from "framer-motion";
export default function AnimatedInputDefault() {
return (
<motion.div
initial={{ opacity: 0, scale: 0.96 }}
animate={{ opacity: 1, scale: 1 }}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
transition={{ type: "spring", stiffness: 350, damping: 25 }}
className="cursor-pointer"
>
<input className="flex h-10 w-full max-w-sm rounded-md border border-input bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2" placeholder="Email" />
</motion.div>
);
} Disabled Input
Install this package in your project before importing the animated component.
npm i framer-motion lucide-react <input disabled class="flex h-10 w-full max-w-sm rounded-md border border-input bg-muted px-3 py-2 text-sm opacity-50 cursor-not-allowed" placeholder="Disabled" /> <input disabled className="flex h-10 w-full max-w-sm rounded-md border border-input bg-muted px-3 py-2 text-sm opacity-50 cursor-not-allowed" placeholder="Disabled" /> "use client";
import React, { useState } from "react";
interface InputDisabledProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
}
export default function InputDisabled({
label = "Email Address",
error,
className = "",
...props
}: InputDisabledProps) {
const [value, setValue] = useState("");
const [isFocused, setIsFocused] = useState(false);
return (
<div className="w-full max-w-xs space-y-1.5">
{label && <label className="text-xs font-semibold text-foreground">{label}</label>}
<div className="relative">
<input
{...props}
value={value}
onChange={(e) => setValue(e.target.value)}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
className={`w-full px-3.5 py-2 text-xs rounded-xl border bg-background text-foreground transition-all focus:outline-hidden ${
isFocused
? "border-primary ring-2 ring-primary/20"
: "border-input hover:border-border"
} ${error ? "border-destructive ring-destructive/20" : ""} ${className}`}
placeholder="Enter value..."
/>
{value && (
<button
type="button"
onClick={() => setValue("")}
className="absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground text-xs"
>
✕
</button>
)}
</div>
{error && <p className="text-[11px] text-destructive">{error}</p>}
</div>
);
} "use client";
import React from "react";
import { motion } from "framer-motion";
export default function AnimatedInputDisabled() {
return (
<motion.div
initial={{ opacity: 0, scale: 0.96 }}
animate={{ opacity: 1, scale: 1 }}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
transition={{ type: "spring", stiffness: 350, damping: 25 }}
className="cursor-pointer"
>
<input disabled className="flex h-10 w-full max-w-sm rounded-md border border-input bg-muted px-3 py-2 text-sm opacity-50 cursor-not-allowed" placeholder="Disabled" />
</motion.div>
);
} File Input
Install this package in your project before importing the animated component.
npm i framer-motion lucide-react <input type="file" class="flex h-10 w-full max-w-sm rounded-md border border-input bg-transparent px-3 py-1.5 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium text-muted-foreground" /> <input type="file" className="flex h-10 w-full max-w-sm rounded-md border border-input bg-transparent px-3 py-1.5 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium text-muted-foreground" /> "use client";
import React, { useState } from "react";
interface InputFileProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
}
export default function InputFile({
label = "Email Address",
error,
className = "",
...props
}: InputFileProps) {
const [value, setValue] = useState("");
const [isFocused, setIsFocused] = useState(false);
return (
<div className="w-full max-w-xs space-y-1.5">
{label && <label className="text-xs font-semibold text-foreground">{label}</label>}
<div className="relative">
<input
{...props}
value={value}
onChange={(e) => setValue(e.target.value)}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
className={`w-full px-3.5 py-2 text-xs rounded-xl border bg-background text-foreground transition-all focus:outline-hidden ${
isFocused
? "border-primary ring-2 ring-primary/20"
: "border-input hover:border-border"
} ${error ? "border-destructive ring-destructive/20" : ""} ${className}`}
placeholder="Enter value..."
/>
{value && (
<button
type="button"
onClick={() => setValue("")}
className="absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground text-xs"
>
✕
</button>
)}
</div>
{error && <p className="text-[11px] text-destructive">{error}</p>}
</div>
);
} "use client";
import React from "react";
import { motion } from "framer-motion";
export default function AnimatedInputFile() {
return (
<motion.div
initial={{ opacity: 0, scale: 0.96 }}
animate={{ opacity: 1, scale: 1 }}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
transition={{ type: "spring", stiffness: 350, damping: 25 }}
className="cursor-pointer"
>
<input type="file" className="flex h-10 w-full max-w-sm rounded-md border border-input bg-transparent px-3 py-1.5 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium text-muted-foreground" />
</motion.div>
);
} Input with Button
Install this package in your project before importing the animated component.
npm i framer-motion lucide-react <div class="flex w-full max-w-sm items-center space-x-2"><input class="flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2" placeholder="Email" /><button class="h-10 px-4 py-2 bg-primary text-primary-foreground rounded-md text-sm font-medium">Subscribe</button></div> <div className="flex w-full max-w-sm items-center space-x-2"><input className="flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2" placeholder="Email" /><button className="h-10 px-4 py-2 bg-primary text-primary-foreground rounded-md text-sm font-medium">Subscribe</button></div> "use client";
import React, { useState } from "react";
interface InputWithButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
children?: React.ReactNode;
isLoading?: boolean;
}
export default function InputWithButton({
children = "Click Me",
isLoading: initialLoading = false,
className = "",
...props
}: InputWithButtonProps) {
const [loading, setLoading] = useState(initialLoading);
const [clicked, setClicked] = useState(false);
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
setClicked(true);
setTimeout(() => setClicked(false), 300);
props.onClick?.(e);
};
return (
<button
{...props}
onClick={handleClick}
className={`inline-flex items-center justify-center gap-2 px-5 py-2.5 rounded-xl font-semibold text-xs transition-all active:scale-95 disabled:opacity-50 disabled:pointer-events-none ${
clicked ? "ring-2 ring-primary/40 ring-offset-2 ring-offset-background" : ""
} ${className || "bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm"}`}
>
{loading && (
<svg className="animate-spin h-3.5 w-3.5" viewBox="0 0 24 24" fill="none">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8H4z" />
</svg>
)}
<span>{children}</span>
</button>
);
} "use client";
import React from "react";
import { motion } from "framer-motion";
export default function AnimatedInputWithButton() {
return (
<motion.button
whileHover={{ scale: 1.04 }}
whileTap={{ scale: 0.96 }}
transition={{ type: "spring", stiffness: 400, damping: 20 }}
className="inline-flex items-center justify-center gap-2 px-6 py-3 rounded-xl bg-primary text-primary-foreground font-semibold text-xs shadow-md hover:bg-primary/90 transition-colors"
>
<span>Interactive Motion Button</span>
<motion.span
animate={{ x: [0, 4, 0] }}
transition={{ repeat: Infinity, duration: 1.5, ease: "easeInOut" }}
>
→
</motion.span>
</motion.button>
);
} Error Input
Install this package in your project before importing the animated component.
npm i framer-motion lucide-react <input class="flex h-10 w-full max-w-sm rounded-md border border-red-500 bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-red-500" placeholder="Error state" /> <input className="flex h-10 w-full max-w-sm rounded-md border border-red-500 bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-red-500" placeholder="Error state" /> "use client";
import React, { useState } from "react";
interface InputErrorProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
}
export default function InputError({
label = "Email Address",
error,
className = "",
...props
}: InputErrorProps) {
const [value, setValue] = useState("");
const [isFocused, setIsFocused] = useState(false);
return (
<div className="w-full max-w-xs space-y-1.5">
{label && <label className="text-xs font-semibold text-foreground">{label}</label>}
<div className="relative">
<input
{...props}
value={value}
onChange={(e) => setValue(e.target.value)}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
className={`w-full px-3.5 py-2 text-xs rounded-xl border bg-background text-foreground transition-all focus:outline-hidden ${
isFocused
? "border-primary ring-2 ring-primary/20"
: "border-input hover:border-border"
} ${error ? "border-destructive ring-destructive/20" : ""} ${className}`}
placeholder="Enter value..."
/>
{value && (
<button
type="button"
onClick={() => setValue("")}
className="absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground text-xs"
>
✕
</button>
)}
</div>
{error && <p className="text-[11px] text-destructive">{error}</p>}
</div>
);
} "use client";
import React from "react";
import { motion } from "framer-motion";
export default function AnimatedInputError() {
return (
<motion.div
initial={{ opacity: 0, scale: 0.96 }}
animate={{ opacity: 1, scale: 1 }}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
transition={{ type: "spring", stiffness: 350, damping: 25 }}
className="cursor-pointer"
>
<input className="flex h-10 w-full max-w-sm rounded-md border border-red-500 bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-red-500" placeholder="Error state" />
</motion.div>
);
} Success Input
Install this package in your project before importing the animated component.
npm i framer-motion lucide-react <input class="flex h-10 w-full max-w-sm rounded-md border border-green-500 bg-transparent px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-green-500" value="valid@email.com" /> <input className="flex h-10 w-full max-w-sm rounded-md border border-green-500 bg-transparent px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-green-500" value="valid@email.com" /> "use client";
import React, { useState } from "react";
interface InputSuccessProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
}
export default function InputSuccess({
label = "Email Address",
error,
className = "",
...props
}: InputSuccessProps) {
const [value, setValue] = useState("");
const [isFocused, setIsFocused] = useState(false);
return (
<div className="w-full max-w-xs space-y-1.5">
{label && <label className="text-xs font-semibold text-foreground">{label}</label>}
<div className="relative">
<input
{...props}
value={value}
onChange={(e) => setValue(e.target.value)}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
className={`w-full px-3.5 py-2 text-xs rounded-xl border bg-background text-foreground transition-all focus:outline-hidden ${
isFocused
? "border-primary ring-2 ring-primary/20"
: "border-input hover:border-border"
} ${error ? "border-destructive ring-destructive/20" : ""} ${className}`}
placeholder="Enter value..."
/>
{value && (
<button
type="button"
onClick={() => setValue("")}
className="absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground text-xs"
>
✕
</button>
)}
</div>
{error && <p className="text-[11px] text-destructive">{error}</p>}
</div>
);
} "use client";
import React from "react";
import { motion } from "framer-motion";
export default function AnimatedInputSuccess() {
return (
<motion.div
initial={{ opacity: 0, scale: 0.96 }}
animate={{ opacity: 1, scale: 1 }}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
transition={{ type: "spring", stiffness: 350, damping: 25 }}
className="cursor-pointer"
>
<input className="flex h-10 w-full max-w-sm rounded-md border border-green-500 bg-transparent px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-green-500" value="valid@email.com" />
</motion.div>
);
} Large Input
Install this package in your project before importing the animated component.
npm i framer-motion lucide-react <input class="flex h-12 w-full max-w-sm rounded-md border border-input bg-transparent px-4 py-3 text-base placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring" placeholder="Large input" /> <input className="flex h-12 w-full max-w-sm rounded-md border border-input bg-transparent px-4 py-3 text-base placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring" placeholder="Large input" /> "use client";
import React, { useState } from "react";
interface InputLargeProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
}
export default function InputLarge({
label = "Email Address",
error,
className = "",
...props
}: InputLargeProps) {
const [value, setValue] = useState("");
const [isFocused, setIsFocused] = useState(false);
return (
<div className="w-full max-w-xs space-y-1.5">
{label && <label className="text-xs font-semibold text-foreground">{label}</label>}
<div className="relative">
<input
{...props}
value={value}
onChange={(e) => setValue(e.target.value)}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
className={`w-full px-3.5 py-2 text-xs rounded-xl border bg-background text-foreground transition-all focus:outline-hidden ${
isFocused
? "border-primary ring-2 ring-primary/20"
: "border-input hover:border-border"
} ${error ? "border-destructive ring-destructive/20" : ""} ${className}`}
placeholder="Enter value..."
/>
{value && (
<button
type="button"
onClick={() => setValue("")}
className="absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground text-xs"
>
✕
</button>
)}
</div>
{error && <p className="text-[11px] text-destructive">{error}</p>}
</div>
);
} "use client";
import React from "react";
import { motion } from "framer-motion";
export default function AnimatedInputLarge() {
return (
<motion.div
initial={{ opacity: 0, scale: 0.96 }}
animate={{ opacity: 1, scale: 1 }}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
transition={{ type: "spring", stiffness: 350, damping: 25 }}
className="cursor-pointer"
>
<input className="flex h-12 w-full max-w-sm rounded-md border border-input bg-transparent px-4 py-3 text-base placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring" placeholder="Large input" />
</motion.div>
);
} Small Input
Install this package in your project before importing the animated component.
npm i framer-motion lucide-react <input class="flex h-8 w-full max-w-sm rounded-md border border-input bg-transparent px-2 py-1 text-xs placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring" placeholder="Small input" /> <input className="flex h-8 w-full max-w-sm rounded-md border border-input bg-transparent px-2 py-1 text-xs placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring" placeholder="Small input" /> "use client";
import React, { useState } from "react";
interface InputSmallProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
}
export default function InputSmall({
label = "Email Address",
error,
className = "",
...props
}: InputSmallProps) {
const [value, setValue] = useState("");
const [isFocused, setIsFocused] = useState(false);
return (
<div className="w-full max-w-xs space-y-1.5">
{label && <label className="text-xs font-semibold text-foreground">{label}</label>}
<div className="relative">
<input
{...props}
value={value}
onChange={(e) => setValue(e.target.value)}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
className={`w-full px-3.5 py-2 text-xs rounded-xl border bg-background text-foreground transition-all focus:outline-hidden ${
isFocused
? "border-primary ring-2 ring-primary/20"
: "border-input hover:border-border"
} ${error ? "border-destructive ring-destructive/20" : ""} ${className}`}
placeholder="Enter value..."
/>
{value && (
<button
type="button"
onClick={() => setValue("")}
className="absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground text-xs"
>
✕
</button>
)}
</div>
{error && <p className="text-[11px] text-destructive">{error}</p>}
</div>
);
} "use client";
import React from "react";
import { motion } from "framer-motion";
export default function AnimatedInputSmall() {
return (
<motion.div
initial={{ opacity: 0, scale: 0.96 }}
animate={{ opacity: 1, scale: 1 }}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
transition={{ type: "spring", stiffness: 350, damping: 25 }}
className="cursor-pointer"
>
<input className="flex h-8 w-full max-w-sm rounded-md border border-input bg-transparent px-2 py-1 text-xs placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring" placeholder="Small input" />
</motion.div>
);
} Icon Left
Install this package in your project before importing the animated component.
npm i framer-motion lucide-react <div class="relative w-full max-w-sm"><svg class="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg><input class="flex h-10 w-full rounded-md border border-input bg-transparent pl-9 pr-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring" placeholder="Search..." /></div> <div className="relative w-full max-w-sm"><svg className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg><input className="flex h-10 w-full rounded-md border border-input bg-transparent pl-9 pr-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring" placeholder="Search..." /></div> "use client";
import React, { useState } from "react";
interface InputIconLeftProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
}
export default function InputIconLeft({
label = "Email Address",
error,
className = "",
...props
}: InputIconLeftProps) {
const [value, setValue] = useState("");
const [isFocused, setIsFocused] = useState(false);
return (
<div className="w-full max-w-xs space-y-1.5">
{label && <label className="text-xs font-semibold text-foreground">{label}</label>}
<div className="relative">
<input
{...props}
value={value}
onChange={(e) => setValue(e.target.value)}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
className={`w-full px-3.5 py-2 text-xs rounded-xl border bg-background text-foreground transition-all focus:outline-hidden ${
isFocused
? "border-primary ring-2 ring-primary/20"
: "border-input hover:border-border"
} ${error ? "border-destructive ring-destructive/20" : ""} ${className}`}
placeholder="Enter value..."
/>
{value && (
<button
type="button"
onClick={() => setValue("")}
className="absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground text-xs"
>
✕
</button>
)}
</div>
{error && <p className="text-[11px] text-destructive">{error}</p>}
</div>
);
} "use client";
import React from "react";
import { motion } from "framer-motion";
export default function AnimatedInputIconLeft() {
return (
<motion.div
initial={{ opacity: 0, scale: 0.96 }}
animate={{ opacity: 1, scale: 1 }}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
transition={{ type: "spring", stiffness: 350, damping: 25 }}
className="cursor-pointer"
>
<div className="relative w-full max-w-sm"><svg className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg><input className="flex h-10 w-full rounded-md border border-input bg-transparent pl-9 pr-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring" placeholder="Search..." /></div>
</motion.div>
);
} Icon Right
Install this package in your project before importing the animated component.
npm i framer-motion lucide-react <div class="relative w-full max-w-sm"><input class="flex h-10 w-full rounded-md border border-input bg-transparent pl-3 pr-9 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring" placeholder="Password" /><svg class="absolute right-2.5 top-2.5 h-4 w-4 text-muted-foreground" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></svg></div> <div className="relative w-full max-w-sm"><input className="flex h-10 w-full rounded-md border border-input bg-transparent pl-3 pr-9 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring" placeholder="Password" /><svg className="absolute right-2.5 top-2.5 h-4 w-4 text-muted-foreground" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></svg></div> "use client";
import React, { useState } from "react";
interface InputIconRightProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
}
export default function InputIconRight({
label = "Email Address",
error,
className = "",
...props
}: InputIconRightProps) {
const [value, setValue] = useState("");
const [isFocused, setIsFocused] = useState(false);
return (
<div className="w-full max-w-xs space-y-1.5">
{label && <label className="text-xs font-semibold text-foreground">{label}</label>}
<div className="relative">
<input
{...props}
value={value}
onChange={(e) => setValue(e.target.value)}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
className={`w-full px-3.5 py-2 text-xs rounded-xl border bg-background text-foreground transition-all focus:outline-hidden ${
isFocused
? "border-primary ring-2 ring-primary/20"
: "border-input hover:border-border"
} ${error ? "border-destructive ring-destructive/20" : ""} ${className}`}
placeholder="Enter value..."
/>
{value && (
<button
type="button"
onClick={() => setValue("")}
className="absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground text-xs"
>
✕
</button>
)}
</div>
{error && <p className="text-[11px] text-destructive">{error}</p>}
</div>
);
} "use client";
import React from "react";
import { motion } from "framer-motion";
export default function AnimatedInputIconRight() {
return (
<motion.div
initial={{ opacity: 0, scale: 0.96 }}
animate={{ opacity: 1, scale: 1 }}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
transition={{ type: "spring", stiffness: 350, damping: 25 }}
className="cursor-pointer"
>
<div className="relative w-full max-w-sm"><input className="flex h-10 w-full rounded-md border border-input bg-transparent pl-3 pr-9 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring" placeholder="Password" /><svg className="absolute right-2.5 top-2.5 h-4 w-4 text-muted-foreground" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></svg></div>
</motion.div>
);
}