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 |
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"
style={{
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"
// Note: UI Toolkit doesn't have a built-in password mask
// You'd need to implement this with a custom element or USS
/>
)
}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.