Skip to main content

Input

The Input component is a flexible, styled text input field with support for floating labels, prefixes, suffixes, info messages, and error states. It can integrate with form libraries (such as React Hook Form) via the register prop and supports multiple size and color variants.

import { Input } from "tawuniya/components";

👉 View in Storybook


Props​

PropTypeDefaultDescription
labelstring—Floating label text displayed inside the input.
prefixstring | React.ReactNode—Optional prefix element displayed before the input.
prefixClassstring—Additional Tailwind classes for the prefix container.
suffixstring | React.ReactNode—Optional suffix element displayed after the input.
suffixClassstring—Additional Tailwind classes for the suffix container.
errorstring—Error message displayed below the input.
infostring—Info message displayed below the input with an info icon.
color"default" | "primary" | "secondary" | "info" | "warning" | "success" | "destructive""default"Color variant for borders and text.
size"sm" | "md" | "lg""md"Input size variant.
registerany—React Hook Form register function for form integration.
disabledbooleanfalseDisables the input.
onChange(value: string) => void—Callback triggered when the input value changes.
classNamestring—Additional Tailwind classes for the input element.
labelSize"sm" | "md" | "lg""sm"Input label size variant.

The component also accepts all native input HTML attributes via React.InputHTMLAttributes<HTMLInputElement>.

Usage​

With Controlled Form​

import { useState } from "react";
import { Input } from "tawuniya/components";

export default function BasicExample() {
const [value, setValue] = useState("");

return (
<Input
label="Username"
placeholder="Enter your username"
value={value}
onChange={setValue}
/>
);
}

With Prefix and Suffix​

import { Input } from "tawuniya/components";
import { Search } from "lucide-react";

export default function PrefixSuffixExample() {
return (
<Input
label="Search"
prefix={<Search size={16} />}
suffix=".com"
placeholder="Search here..."
/>
);
}

With Info and Error Messages​

import { useState } from "react";
import { Input } from "tawuniya/components";

export default function InfoErrorExample() {
const [email, setEmail] = useState("");

return (
<Input
label="Email Address"
value={email}
onChange={setEmail}
info="We will not share your email."
error={email && !email.includes("@") ? "Invalid email format" : ""}
/>
);
}

With React Hook Form (register)​

import { useForm } from "react-hook-form";
import { Input } from "tawuniya/components";

export default function FormExample() {
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
defaultValues: { username: "" },
});

const onSubmit = (data: any) => {
console.log(data);
};

return (
<form onSubmit={handleSubmit(onSubmit)}>
<Input
name="username"
label="Username"
placeholder="Enter your username"
register={register}
error={errors.username.message}
/>
<button type="submit">Submit</button>
</form>
);
}

Variants​

  • Size

    • sm → Compact height and text size
    • md → Medium height and text size
    • lg → Large height and text size
  • Color

    • default, primary, secondary, info, warning, success, destructive
  • States

    • disabled → Disables interaction
    • error → Highlights in red and shows error message
    • info → Displays helper information with icon

Accessibility​

  • Uses semantic <label> for input association.
  • Floating label moves when input is focused or has value.

Notes​

  • Prefix and suffix containers have fixed width; adjust via prefixClass or suffixClass if needed.
  • Floating label works only if label is provided.