TextField#
TextField is a text input. Maps to UI Toolkit's TextField.
Import#
import { TextField } from "onejs-react"Basic Usage#
function NameInput() {
const [name, setName] = useState("")
return (
<TextField
value={name}
onChange={(e) => setName(e.value)}
placeholder="Enter your name"
/>
)
}Props#
| Prop | Type | Description |
|---|---|---|
value | string | Current text value |
placeholder | string | Placeholder text |
multiline | boolean | Enable multiline input |
readOnly | boolean | Make field read-only |
maxLength | number | Maximum character count |
label | string | Label shown beside the field |
isPasswordField | boolean | Mask the typed characters |
isDelayed | boolean | Fire onChange only on Enter or when focus leaves, not on every keystroke |
selectAllOnFocus | boolean | Select the whole text when the field gains focus |
selectAllOnMouseUp | boolean | Select the whole text when a click is released in the field |
hideMobileInput | boolean | Hide the on-screen keyboard's own input box on mobile |
autoCorrection | boolean | Allow the mobile keyboard's autocorrection |
style | ViewStyle | Inline styles (outer field) |
className | string | USS class name(s) (outer field) |
inputStyle | ViewStyle | Inline styles for the inner input |
inputClassName | string | USS class name(s) for the inner input |
onChange | (e) => void | Value change handler |
onFocus | (e) => void | Focus handler |
onBlur | (e) => void | Blur handler |
Controlled Input#
function SearchBox() {
const [query, setQuery] = useState("")
const handleSearch = () => {
console.log("Searching for:", query)
}
return (
<View style={{ flexDirection: "row" }}>
<TextField
value={query}
onChange={(e) => setQuery(e.value)}
placeholder="Search..."
style={{ flexGrow: 1, marginRight: 10 }}
/>
<Button text="Search" onClick={handleSearch} />
</View>
)
}Multiline#
<TextField
value={description}
onChange={(e) => setDescription(e.value)}
placeholder="Enter description..."
multiline={true}
style={{ height: 100 }}
/>Validation#
function EmailInput() {
const [email, setEmail] = useState("")
const [error, setError] = useState("")
const validate = (value) => {
if (!value.includes("@")) {
setError("Please enter a valid email")
} else {
setError("")
}
}
return (
<View>
<TextField
value={email}
onChange={(e) => {
setEmail(e.value)
validate(e.value)
}}
placeholder="Email address"
inputStyle={{
borderColor: error ? "#ff0000" : "#333",
}}
/>
{error && <Label text={error} style={{ color: "#ff0000", fontSize: 12 }} />}
</View>
)
}Password Field#
function PasswordInput() {
const [password, setPassword] = useState("")
return (
<TextField
value={password}
onChange={(e) => setPassword(e.value)}
placeholder="Password"
isPasswordField
/>
)
}Styling the Inner Input#
A TextField is two elements: an outer field and an inner input, and the visible box (border, background, padding) lives on the inner one. style and className land on the outer field, so styling the box goes through inputStyle and inputClassName:
<TextField
value={text}
onChange={(e) => setText(e.value)}
inputStyle={{
backgroundColor: "#2a2a2a",
borderWidth: 1,
borderColor: "#444",
borderRadius: 4,
paddingTop: 10,
paddingBottom: 10,
paddingLeft: 12,
paddingRight: 12,
fontSize: 16,
color: "#ffffff",
}}
/>inputClassName takes USS classes, Tailwind utilities included:
<TextField inputClassName="bg-gray-900 border-none rounded-lg" />Inline inputStyle always wins, including over the theme's hover and focus rules. Classes win over the theme's resting look but not over its hover/focus, which use higher-specificity selectors; enable preflight to strip those, or use onejs-ui's Input, which handles all of it.