The Input component provides a text input field with support for placeholders, validation, password mode, and different visual styles.
Basic Usage
use freya::prelude::*;
fn app() -> impl IntoElement {
let text = use_state(String::new);
Input::new(text)
.placeholder("Type something...")
}
Style Variants
Normal (Default)
let text = use_state(String::new);
Input::new(text)
.placeholder("Normal input")
Filled
let text = use_state(String::new);
Input::new(text)
.placeholder("Filled input")
.filled()
Flat
let text = use_state(String::new);
Input::new(text)
.placeholder("Flat input")
.flat()
Layout Variants
Compact
Input::new(text)
.placeholder("Compact")
.compact()
Expanded
Input::new(text)
.placeholder("Expanded")
.expanded()
Password Mode
Hide input text for passwords:
let password = use_state(String::new);
Input::new(password)
.placeholder("Enter password")
.mode(InputMode::new_password())
Or use a custom masking character:
Input::new(password)
.mode(InputMode::Hidden('•'))
Properties
The text value (typically from use_state)
placeholder
impl Into<Cow<'static, str>>
Placeholder text shown when input is empty
on_validate
EventHandler<InputValidator>
Callback for validating input changes. Set validator.set_valid(false) to reject changes
Callback fired when Enter key is pressed
mode
InputMode
default:"InputMode::Shown"
Display mode: Shown or Hidden(char) for passwords
Whether to automatically focus when mounted
Whether the input can be interacted with
width
Size
default:"Size::px(150.)"
Width of the input field
Text alignment within the input
Visual style: Normal, Filled, or Flat
Size variant: Normal, Compact, or Expanded
Validation Example
Validate input to only allow numbers:
use freya::prelude::*;
fn app() -> impl IntoElement {
let text = use_state(String::new);
Input::new(text)
.placeholder("Numbers only")
.on_validate(move |validator: InputValidator| {
let is_valid = validator.text().chars().all(|c| c.is_numeric());
validator.set_valid(is_valid);
})
}
Submit Handler Example
Handle form submission:
let text = use_state(String::new);
let mut submitted = use_state(|| None::<String>);
rect()
.spacing(8.)
.child(
Input::new(text)
.placeholder("Enter text and press Enter")
.on_submit(move |value| {
submitted.set(Some(value));
text.set(String::new());
})
)
.child(
submitted()
.as_ref()
.map(|s| format!("Submitted: {}", s))
.unwrap_or_default()
)
Complete Example
use freya::prelude::*;
fn app() -> impl IntoElement {
let username = use_state(String::new);
let password = use_state(String::new);
let mut message = use_state(|| String::new());
let on_login = move |_| {
if !username().is_empty() && !password().is_empty() {
message.set(format!("Logging in as {}...", username()));
}
};
rect()
.center()
.spacing(12.)
.child(
Input::new(username)
.placeholder("Username")
.width(Size::px(200.))
)
.child(
Input::new(password)
.placeholder("Password")
.mode(InputMode::new_password())
.width(Size::px(200.))
)
.child(
Button::new()
.on_press(on_login)
.filled()
.child("Login")
)
.child(message())
}
Text Editing
The input supports standard text editing features:
- Selection: Click and drag to select text
- Cut/Copy/Paste: Standard keyboard shortcuts
- Undo/Redo: Ctrl+Z / Ctrl+Y
- Navigation: Arrow keys, Home, End
- Deletion: Backspace, Delete
Accessibility
role="textInput" (or "passwordInput" in password mode)
- Keyboard navigation with Tab
- Focus indicators
- Screen reader support
Theming
Customize appearance:
Input::new(text)
.theme_colors(InputColorsThemePartial {
background: Some(Color::from_rgb(240, 240, 255)),
color: Some(Color::BLACK),
..Default::default()
})
Source
View the full implementation: input.rs