This commit is contained in:
Mitchell Marino 2024-06-19 09:12:39 -05:00
parent 5f4358277e
commit 7c4e3b162d
7 changed files with 132 additions and 144 deletions

View File

@ -62,11 +62,7 @@ impl<FD: FormToolData> FormBuilder<FD> {
let view = match show_when { let view = match show_when {
Some(when) => { Some(when) => {
let when = move || when(fd.into(), cx.clone()); let when = move || when(fd.into(), cx.clone());
view! { view! { <Show when=when>{view.clone()}</Show> }
<Show when=when>
{view.clone()}
</Show>
}
} }
None => view(), None => view(),
}; };

View File

@ -13,7 +13,10 @@ pub struct SelectData {
/// The options for the select. /// The options for the select.
/// ///
/// The first value is the string to display, the second is the value. /// The first value is the string to display, the second is the value.
// TODO: maybe signal?
pub options: Vec<(String, String)>, pub options: Vec<(String, String)>,
/// The display text for the blank option, if there is one.
pub blank_option: Option<String>,
} }
impl ControlData for SelectData { impl ControlData for SelectData {
@ -107,4 +110,17 @@ impl<FD: FormToolData, FDT> ControlBuilder<FD, SelectData, FDT> {
} }
self self
} }
/// Adds a blank option as the first option for the select.
pub fn with_blank_option(mut self) -> Self {
self.data.blank_option = Some(String::new());
self
}
/// Adds a blank option as the first option for the select,
/// but sets the display string to the given value.
pub fn with_blank_option_displayed(mut self, display: impl ToString) -> Self {
self.data.blank_option = Some(display.to_string());
self
}
} }

View File

@ -37,6 +37,8 @@ impl<FD: FormToolData> FormBuilder<FD> {
impl<FD: FormToolData> VanityControlBuilder<FD, SpacerData> { impl<FD: FormToolData> VanityControlBuilder<FD, SpacerData> {
/// Sets the height of the spacer. /// Sets the height of the spacer.
/// ///
/// This is a string to allow different units like "10px" or "1.25em".
///
/// This may or may not be respected based on the Style implementation. /// This may or may not be respected based on the Style implementation.
pub fn height(mut self, height: impl ToString) -> Self { pub fn height(mut self, height: impl ToString) -> Self {
self.data.height = Some(height.to_string()); self.data.height = Some(height.to_string());

View File

@ -9,9 +9,8 @@ use std::rc::Rc;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct TextAreaData { pub struct TextAreaData {
pub name: String, pub name: String,
pub placeholder: Option<String>,
pub label: Option<String>, pub label: Option<String>,
pub initial_text: String, pub placeholder: Option<String>,
} }
impl ControlData for TextAreaData { impl ControlData for TextAreaData {
@ -70,10 +69,4 @@ impl<FD: FormToolData, FDT> ControlBuilder<FD, TextAreaData, FDT> {
self.data.placeholder = Some(placeholder.to_string()); self.data.placeholder = Some(placeholder.to_string());
self self
} }
/// Sets the intial_text for the text area.
pub fn initial_text(mut self, text: impl ToString) -> Self {
self.data.initial_text = text.to_string();
self
}
} }

View File

@ -9,9 +9,8 @@ use std::rc::Rc;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TextInputData { pub struct TextInputData {
pub name: String, pub name: String,
pub placeholder: Option<String>,
pub label: Option<String>, pub label: Option<String>,
pub initial_text: String, pub placeholder: Option<String>,
pub input_type: &'static str, pub input_type: &'static str,
} }
@ -21,7 +20,6 @@ impl Default for TextInputData {
name: String::new(), name: String::new(),
placeholder: None, placeholder: None,
label: None, label: None,
initial_text: String::new(),
input_type: "input", input_type: "input",
} }
} }
@ -84,12 +82,6 @@ impl<FD: FormToolData, FDT> ControlBuilder<FD, TextInputData, FDT> {
self self
} }
/// Sets the intial_text for the text input.
pub fn initial_text(mut self, text: impl ToString) -> Self {
self.data.initial_text = text.to_string();
self
}
/// Sets the text input to be the "password" type. /// Sets the text input to be the "password" type.
pub fn password(mut self) -> Self { pub fn password(mut self) -> Self {
self.data.input_type = "password"; self.data.input_type = "password";

View File

@ -121,11 +121,7 @@ impl<FD: FormToolData> FormBuilder<FD> {
let view = match show_when { let view = match show_when {
Some(when) => { Some(when) => {
let when = move || when(fd.into(), cx.clone()); let when = move || when(fd.into(), cx.clone());
view! { view! { <Show when=when>{view.clone()}</Show> }
<Show when=when>
{view.clone()}
</Show>
}
} }
None => view(), None => view(),
}; };
@ -268,11 +264,7 @@ impl<FD: FormToolData> FormBuilder<FD> {
let view = match show_when { let view = match show_when {
Some(when) => { Some(when) => {
let when = move || when(fd.into(), cx.clone()); let when = move || when(fd.into(), cx.clone());
view! { view! { <Show when=when>{view.clone()}</Show> }
<Show when=when>
{view.clone()}
</Show>
}
} }
None => view(), None => view(),
}; };

View File

@ -60,11 +60,7 @@ impl FormStyle for GridFormStyle {
} }
fn group(&self, group: Rc<ControlRenderData<Self, View>>) -> View { fn group(&self, group: Rc<ControlRenderData<Self, View>>) -> View {
let view = view! { let view = view! { <div class="form_group form_grid">{&group.data}</div> }
<div class="form_group form_grid">
{&group.data}
</div>
}
.into_view(); .into_view();
self.custom_component(&group.styles, view) self.custom_component(&group.styles, view)
@ -105,11 +101,7 @@ impl FormStyle for GridFormStyle {
}; };
let view = view! { let view = view! {
<button <button type="button" class="form_button" on:click=on_click>
type="button"
class="form_button"
on:click=on_click
>
{&control.data.text} {&control.data.text}
</button> </button>
} }
@ -133,7 +125,13 @@ impl FormStyle for GridFormStyle {
value_getter: Option<Signal<String>>, value_getter: Option<Signal<String>>,
) -> View { ) -> View {
let value_getter = move || value_getter.map(|g| g.get()); let value_getter = move || value_getter.map(|g| g.get());
view! { <input name=&control.data.name prop:value=value_getter style="visibility: hidden; column-span: none"/> } view! {
<input
name=&control.data.name
prop:value=value_getter
style="visibility: hidden; column-span: none"
/>
}
.into_view() .into_view()
} }
@ -160,6 +158,7 @@ impl FormStyle for GridFormStyle {
on:focusout=move |ev| { on:focusout=move |ev| {
value_setter(event_target_value(&ev)); value_setter(event_target_value(&ev));
} }
class="form_input" class="form_input"
class=("form_input_invalid", move || validation_state.get().is_err()) class=("form_input_invalid", move || validation_state.get().is_err())
/> />
@ -177,7 +176,6 @@ impl FormStyle for GridFormStyle {
validation_state: Signal<Result<(), String>>, validation_state: Signal<Result<(), String>>,
) -> View { ) -> View {
let view = view! { let view = view! {
<div>
<div> <div>
<label for=&control.data.name class="form_label"> <label for=&control.data.name class="form_label">
{control.data.label.as_ref()} {control.data.label.as_ref()}
@ -188,15 +186,14 @@ impl FormStyle for GridFormStyle {
id=&control.data.name id=&control.data.name
name=&control.data.name name=&control.data.name
placeholder=control.data.placeholder.as_ref() placeholder=control.data.placeholder.as_ref()
class="form_input"
prop:value=move || value_getter.get() prop:value=move || value_getter.get()
on:change=move |ev| { on:focusout=move |ev| {
value_setter(event_target_value(&ev)); value_setter(event_target_value(&ev));
} }
>
</textarea>
</div> class="form_input"
class=("form_input_invalid", move || validation_state.get().is_err())
></textarea>
} }
.into_view(); .into_view();
@ -355,12 +352,13 @@ impl FormStyle for GridFormStyle {
id=&control.data.name id=&control.data.name
name=&control.data.name name=&control.data.name
step=control.data.step step=control.data.step
min=control.data.min
max=control.data.max
class="form_input"
prop:value=move || value_getter.get() prop:value=move || value_getter.get()
on:change=move |ev| { on:change=move |ev| {
value_setter(event_target_value(&ev)); value_setter(event_target_value(&ev));
} }
class="form_input"
/> />
} }
.into_view(); .into_view();
@ -388,6 +386,7 @@ impl FormStyle for GridFormStyle {
name=&control.data.name name=&control.data.name
min=control.data.min min=control.data.min
max=control.data.max max=control.data.max
class="form_input"
prop:value=move || value_getter.get() prop:value=move || value_getter.get()
on:input=move |ev| { on:input=move |ev| {
let value = event_target_value(&ev).parse::<i32>().ok(); let value = event_target_value(&ev).parse::<i32>().ok();
@ -395,8 +394,6 @@ impl FormStyle for GridFormStyle {
value_setter(value); value_setter(value);
} }
} }
class="form_input"
/> />
} }
.into_view(); .into_view();