@mshafiqyajid/react-text-input
Headless text input hook + styled component. Supports text/email/password/url/search/tel. Size + tone variants, prefix/suffix icon slots, optional clear (β) button, hint + error message states, controlled or uncontrolled.
Playground #
Props
TSX
import { TextInputStyled } from "@mshafiqyajid/react-text-input/styled";
import "@mshafiqyajid/react-text-input/styles.css";
<TextInputStyled
value={value}
onChange={setValue}
placeholder="Type somethingβ¦"
type="email"
label="Email"
block
clearable
/>Install #
npm install @mshafiqyajid/react-text-input Quick start #
import { TextInputStyled } from "@mshafiqyajid/react-text-input/styled";
import "@mshafiqyajid/react-text-input/styles.css";
const [email, setEmail] = useState("");
<TextInputStyled
type="email"
placeholder="you@example.com"
value={email}
onChange={setEmail}
clearable
/> Validation #
Pass an error message to flip tone to danger and render the message under the field. Use hint for plain helper text.
<TextInputStyled
type="email"
value={email}
onChange={setEmail}
error={!email.includes("@") ? "Invalid email" : undefined}
/> Prefix / suffix #
<TextInputStyled
prefix={<SearchIcon />}
placeholder="Searchβ¦"
/>
<TextInputStyled
prefix={<span>$</span>}
suffix={<span>USD</span>}
placeholder="0.00"
/> Headless #
import { useTextInput } from "@mshafiqyajid/react-text-input";
const { inputProps, value, clear, isEmpty } = useTextInput({
defaultValue: "",
});
return (
<span>
<input {...inputProps} />
{!isEmpty && <button onClick={clear}>Γ</button>}
</span>
); API #
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | β | Controlled value |
| defaultValue | string | "" | Uncontrolled initial value |
| onChange | (value: string) => void | β | Called on every change |
| type | "text" | "email" | "password" | "url" | "search" | "tel" | "text" | Input type |
| size | "sm" | "md" | "lg" | "md" | Size |
| tone | "neutral" | "primary" | "success" | "danger" | "neutral" | Color |
| label | ReactNode | β | Field label rendered above the input |
| required | boolean | false | Append a red asterisk to the label |
| block | boolean | false | Full-width |
| clearable | boolean | false | Show clear (β) button when value is non-empty |
| passwordToggle | boolean | false | For type="password": show an eye toggle that reveals/hides |
| loading | boolean | false | Show a spinner suffix while async work runs |
| success | boolean | false | Apply success tone + show a green check suffix |
| maxLength | number | β | Max characters; auto-shows a counter |
| showCount | boolean | auto | Force-show or hide the character counter |
| prefix | ReactNode | β | Slot before the input |
| suffix | ReactNode | β | Slot after the input |
| hint | ReactNode | β | Helper text below the field |
| error | ReactNode | β | Error message β auto-applies danger tone |
| disabled | boolean | false | Disable |
| readOnly | boolean | false | Read only |