use std::borrow::Cow;
use iced::widget::text_input;
use iced::{Element, Length};
use iced_plus_theme::{AppTheme, TextInputClass};
pub struct TextInput<'a, Message> {
id: Option<text_input::Id>,
placeholder: Cow<'a, str>,
value: &'a str,
label: Option<Cow<'a, str>>,
helper: Option<Cow<'a, str>>,
error: Option<Cow<'a, str>>,
on_input: Option<Box<dyn Fn(String) -> Message + 'a>>,
on_submit: Option<Message>,
width: Length,
padding: f32,
size: f32,
class: TextInputClass,
secure: bool,
}
impl<'a, Message> TextInput<'a, Message> {
#[must_use]
pub fn new(placeholder: impl Into<Cow<'a, str>>, value: &'a str) -> Self {
Self {
id: None,
placeholder: placeholder.into(),
value,
label: None,
helper: None,
error: None,
on_input: None,
on_submit: None,
width: Length::Fill,
padding: 10.0,
size: 14.0,
class: TextInputClass::Default,
secure: false,
}
}
#[must_use]
pub fn id(mut self, id: text_input::Id) -> Self {
self.id = Some(id);
self
}
#[must_use]
pub fn label(mut self, label: impl Into<Cow<'a, str>>) -> Self {
self.label = Some(label.into());
self
}
#[must_use]
pub fn helper(mut self, helper: impl Into<Cow<'a, str>>) -> Self {
self.helper = Some(helper.into());
self
}
#[must_use]
pub fn error(mut self, error: impl Into<Cow<'a, str>>) -> Self {
self.error = Some(error.into());
self
}
#[must_use]
pub fn on_input<F>(mut self, f: F) -> Self
where
F: Fn(String) -> Message + 'a,
{
self.on_input = Some(Box::new(f));
self
}
#[must_use]
pub fn on_submit(mut self, message: Message) -> Self {
self.on_submit = Some(message);
self
}
#[must_use]
pub fn width(mut self, width: impl Into<Length>) -> Self {
self.width = width.into();
self
}
#[must_use]
pub fn padding(mut self, padding: f32) -> Self {
self.padding = padding;
self
}
#[must_use]
pub fn size(mut self, size: f32) -> Self {
self.size = size;
self
}
#[must_use]
pub fn filled(mut self) -> Self {
self.class = TextInputClass::Filled;
self
}
#[must_use]
pub fn secure(mut self, secure: bool) -> Self {
self.secure = secure;
self
}
#[must_use]
pub fn password(self) -> Self {
self.secure(true)
}
}
impl<'a, Message: Clone + 'a> From<TextInput<'a, Message>> for Element<'a, Message, AppTheme<'a>> {
fn from(input: TextInput<'a, Message>) -> Self {
let mut widget = text_input(&input.placeholder, input.value)
.padding(input.padding)
.size(input.size)
.width(input.width)
.class(input.class)
.secure(input.secure);
if let Some(id) = input.id {
widget = widget.id(id);
}
if let Some(on_input) = input.on_input {
widget = widget.on_input(on_input);
}
if let Some(msg) = input.on_submit {
widget = widget.on_submit(msg);
}
widget.into()
}
}
impl<'a, Message: Clone + 'a> From<TextInput<'a, Message>> for Element<'a, Message, iced::Theme> {
fn from(input: TextInput<'a, Message>) -> Self {
let mut widget = text_input(&input.placeholder, input.value)
.padding(input.padding)
.size(input.size)
.width(input.width)
.secure(input.secure);
if let Some(id) = input.id {
widget = widget.id(id);
}
if let Some(on_input) = input.on_input {
widget = widget.on_input(on_input);
}
if let Some(msg) = input.on_submit {
widget = widget.on_submit(msg);
}
widget.into()
}
}