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 {
Some(when) => {
let when = move || when(fd.into(), cx.clone());
view! {
<Show when=when>
{view.clone()}
</Show>
}
view! { <Show when=when>{view.clone()}</Show> }
}
None => view(),
};

View File

@ -13,7 +13,10 @@ pub struct SelectData {
/// The options for the select.
///
/// The first value is the string to display, the second is the value.
// TODO: maybe signal?
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 {
@ -107,4 +110,17 @@ impl<FD: FormToolData, FDT> ControlBuilder<FD, SelectData, FDT> {
}
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> {
/// 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.
pub fn height(mut self, height: impl ToString) -> Self {
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)]
pub struct TextAreaData {
pub name: String,
pub placeholder: Option<String>,
pub label: Option<String>,
pub initial_text: String,
pub placeholder: Option<String>,
}
impl ControlData for TextAreaData {
@ -70,10 +69,4 @@ impl<FD: FormToolData, FDT> ControlBuilder<FD, TextAreaData, FDT> {
self.data.placeholder = Some(placeholder.to_string());
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)]
pub struct TextInputData {
pub name: String,
pub placeholder: Option<String>,
pub label: Option<String>,
pub initial_text: String,
pub placeholder: Option<String>,
pub input_type: &'static str,
}
@ -21,7 +20,6 @@ impl Default for TextInputData {
name: String::new(),
placeholder: None,
label: None,
initial_text: String::new(),
input_type: "input",
}
}
@ -84,12 +82,6 @@ impl<FD: FormToolData, FDT> ControlBuilder<FD, TextInputData, FDT> {
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.
pub fn password(mut self) -> Self {
self.data.input_type = "password";

View File

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

View File

@ -60,11 +60,7 @@ impl FormStyle for GridFormStyle {
}
fn group(&self, group: Rc<ControlRenderData<Self, View>>) -> View {
let view = view! {
<div class="form_group form_grid">
{&group.data}
</div>
}
let view = view! { <div class="form_group form_grid">{&group.data}</div> }
.into_view();
self.custom_component(&group.styles, view)
@ -105,11 +101,7 @@ impl FormStyle for GridFormStyle {
};
let view = view! {
<button
type="button"
class="form_button"
on:click=on_click
>
<button type="button" class="form_button" on:click=on_click>
{&control.data.text}
</button>
}
@ -133,7 +125,13 @@ impl FormStyle for GridFormStyle {
value_getter: Option<Signal<String>>,
) -> View {
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()
}
@ -160,6 +158,7 @@ impl FormStyle for GridFormStyle {
on:focusout=move |ev| {
value_setter(event_target_value(&ev));
}
class="form_input"
class=("form_input_invalid", move || validation_state.get().is_err())
/>
@ -178,25 +177,23 @@ impl FormStyle for GridFormStyle {
) -> View {
let view = view! {
<div>
<div>
<label for=&control.data.name class="form_label">
{control.data.label.as_ref()}
</label>
<span class="form_error">{move || validation_state.get().err()}</span>
</div>
<textarea
id=&control.data.name
name=&control.data.name
placeholder=control.data.placeholder.as_ref()
class="form_input"
prop:value=move || value_getter.get()
on:change=move |ev| {
value_setter(event_target_value(&ev));
}
>
</textarea>
<label for=&control.data.name class="form_label">
{control.data.label.as_ref()}
</label>
<span class="form_error">{move || validation_state.get().err()}</span>
</div>
<textarea
id=&control.data.name
name=&control.data.name
placeholder=control.data.placeholder.as_ref()
prop:value=move || value_getter.get()
on:focusout=move |ev| {
value_setter(event_target_value(&ev));
}
class="form_input"
class=("form_input_invalid", move || validation_state.get().is_err())
></textarea>
}
.into_view();
@ -242,18 +239,18 @@ impl FormStyle for GridFormStyle {
.collect_view();
let view = view! {
<div>
<label for=&control.data.name class="form_label">
{control.data.label.as_ref()}
</label>
<span class="form_error">{move || validation_state.get().err()}</span>
</div>
<div
class="form_input"
class:form_input_invalid=move || validation_state.get().is_err()
>
{buttons_view}
</div>
<div>
<label for=&control.data.name class="form_label">
{control.data.label.as_ref()}
</label>
<span class="form_error">{move || validation_state.get().err()}</span>
</div>
<div
class="form_input"
class:form_input_invalid=move || validation_state.get().is_err()
>
{buttons_view}
</div>
}
.into_view();
@ -283,23 +280,23 @@ impl FormStyle for GridFormStyle {
.collect_view();
let view = view! {
<div>
<label for=&control.data.name class="form_label">
{control.data.label.as_ref()}
</label>
<span class="form_error">{move || validation_state.get().err()}</span>
</div>
<select
id=&control.data.name
name=&control.data.name
class="form_input"
on:input=move |ev| {
value_setter(event_target_value(&ev));
}
>
<div>
<label for=&control.data.name class="form_label">
{control.data.label.as_ref()}
</label>
<span class="form_error">{move || validation_state.get().err()}</span>
</div>
<select
id=&control.data.name
name=&control.data.name
class="form_input"
on:input=move |ev| {
value_setter(event_target_value(&ev));
}
>
{options_view}
</select>
{options_view}
</select>
}
.into_view();
@ -313,23 +310,23 @@ impl FormStyle for GridFormStyle {
value_setter: Rc<dyn Fn(<CheckboxData as ControlData>::ReturnType)>,
) -> View {
let view = view! {
<label for=&control.data.name class="form_label">
{control.data.label.as_ref()}
</label>
<label class="form_input" for=&control.data.name>
<input
type="checkbox"
id=&control.data.name
name=&control.data.name
prop:checked=value_getter
on:input=move |ev| {
let new_value = event_target_checked(&ev);
value_setter(new_value);
}
/>
<label for=&control.data.name class="form_label">
{control.data.label.as_ref()}
</label>
<label class="form_input" for=&control.data.name>
<input
type="checkbox"
id=&control.data.name
name=&control.data.name
prop:checked=value_getter
on:input=move |ev| {
let new_value = event_target_checked(&ev);
value_setter(new_value);
}
/>
<span>{control.data.label.as_ref()}</span>
</label>
<span>{control.data.label.as_ref()}</span>
</label>
}
.into_view();
@ -344,24 +341,25 @@ impl FormStyle for GridFormStyle {
validation_state: Signal<Result<(), String>>,
) -> View {
let view = view! {
<div>
<label for=&control.data.name class="form_label">
{control.data.label.as_ref()}
</label>
<span class="form_error">{move || validation_state.get().err()}</span>
</div>
<input
type="number"
id=&control.data.name
name=&control.data.name
step=control.data.step
prop:value=move || value_getter.get()
on:change=move |ev| {
value_setter(event_target_value(&ev));
}
class="form_input"
/>
<div>
<label for=&control.data.name class="form_label">
{control.data.label.as_ref()}
</label>
<span class="form_error">{move || validation_state.get().err()}</span>
</div>
<input
type="number"
id=&control.data.name
name=&control.data.name
step=control.data.step
min=control.data.min
max=control.data.max
class="form_input"
prop:value=move || value_getter.get()
on:change=move |ev| {
value_setter(event_target_value(&ev));
}
/>
}
.into_view();
@ -376,28 +374,27 @@ impl FormStyle for GridFormStyle {
validation_state: Signal<Result<(), String>>,
) -> View {
let view = view! {
<div>
<label for=&control.data.name class="form_label">
{control.data.label.as_ref()}
</label>
<span class="form_error">{move || validation_state.get().err()}</span>
</div>
<input
type="range"
id=&control.data.name
name=&control.data.name
min=control.data.min
max=control.data.max
prop:value=move || value_getter.get()
on:input=move |ev| {
let value = event_target_value(&ev).parse::<i32>().ok();
if let Some(value) = value {
value_setter(value);
}
<div>
<label for=&control.data.name class="form_label">
{control.data.label.as_ref()}
</label>
<span class="form_error">{move || validation_state.get().err()}</span>
</div>
<input
type="range"
id=&control.data.name
name=&control.data.name
min=control.data.min
max=control.data.max
class="form_input"
prop:value=move || value_getter.get()
on:input=move |ev| {
let value = event_target_value(&ev).parse::<i32>().ok();
if let Some(value) = value {
value_setter(value);
}
class="form_input"
/>
}
/>
}
.into_view();