diff --git a/src/controls/button.rs b/src/controls/button.rs index 1b72b24..e79556b 100644 --- a/src/controls/button.rs +++ b/src/controls/button.rs @@ -1,48 +1,57 @@ -use super::{ControlRenderData, VanityControlBuilder, VanityControlData}; +use super::ControlRenderData; use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle}; -use leptos::{RwSignal, Signal, View}; +use leptos::RwSignal; use std::rc::Rc; use web_sys::MouseEvent; -#[derive(Clone)] +#[derive(Default, Clone)] pub struct ButtonData { pub(crate) text: String, pub(crate) action: Option>, - - // this will need to be set before calling the build method - pub(crate) fd_signal: RwSignal, -} - -impl VanityControlData for ButtonData { - fn build_control( - fs: &FS, - control: ControlRenderData, - _value_getter: Option>, - ) -> View { - fs.button(control) - } } impl FormBuilder { pub fn button( mut self, - builder: impl Fn( - VanityControlBuilder>, - ) -> VanityControlBuilder>, + builder: impl Fn(ButtonBuilder) -> ButtonBuilder, ) -> Self { - let data = ButtonData { - text: String::default(), - action: None, - fd_signal: self.fd, + let button_builder = ButtonBuilder::new(); + let control = builder(button_builder); + + let render_data = ControlRenderData { + data: Box::new(control.data), + styles: control.styles, }; - let vanity_builder = VanityControlBuilder::new(data); - let control = builder(vanity_builder); - self.add_vanity(control); + + let render_fn = move |fs: &FS, fd: RwSignal| { + let view = fs.button(render_data, fd); + (view, None) + }; + self.render_fns.push(Box::new(render_fn)); + self } } -impl VanityControlBuilder> { +#[derive(Clone)] +pub struct ButtonBuilder { + pub(crate) styles: Vec, + pub(crate) data: ButtonData, +} + +impl ButtonBuilder { + fn new() -> Self { + ButtonBuilder { + styles: Vec::default(), + data: ButtonData::default(), + } + } + + pub fn style(mut self, style: FS::StylingAttributes) -> Self { + self.styles.push(style); + self + } + pub fn text(mut self, text: impl ToString) -> Self { self.data.text = text.to_string(); self diff --git a/src/controls/mod.rs b/src/controls/mod.rs index 751cf82..e8b4509 100644 --- a/src/controls/mod.rs +++ b/src/controls/mod.rs @@ -71,7 +71,7 @@ pub trait ValidatedControlData: ControlData {} /// The data needed to render a interactive control of type `C`. pub struct ControlRenderData { pub data: Box, - pub style: Vec, + pub styles: Vec, } /// The data needed to render a read-only control of type `C`. @@ -101,7 +101,7 @@ impl VanityControlBuilder BuiltVanityControlData { render_data: ControlRenderData { data: Box::new(self.data), - style: self.style_attributes, + styles: self.style_attributes, }, getter: self.getter, } @@ -209,7 +209,7 @@ impl ControlBuilder, - pub(crate) options: Vec, + pub(crate) options: Vec<(String, String)>, } impl ControlData for SelectData { @@ -50,13 +49,36 @@ impl ControlBuilder Self { - self.data.options.push(option.to_string()); + self.data + .options + .push((option.to_string(), option.to_string())); + self + } + + pub fn with_option_valued(mut self, display: impl ToString, value: impl ToString) -> Self { + self.data + .options + .push((display.to_string(), value.to_string())); self } pub fn with_options(mut self, options: impl Iterator) -> Self { for option in options { - self.data.options.push(option.to_string()); + self.data + .options + .push((option.to_string(), option.to_string())); + } + self + } + + pub fn with_options_valued( + mut self, + options: impl Iterator, + ) -> Self { + for option in options { + self.data + .options + .push((option.0.to_string(), option.1.to_string())); } self } diff --git a/src/styles/grid_form.rs b/src/styles/grid_form.rs index dc6cf9e..81ca54f 100644 --- a/src/styles/grid_form.rs +++ b/src/styles/grid_form.rs @@ -1,8 +1,11 @@ use super::FormStyle; -use crate::controls::{ - checkbox::CheckboxData, heading::HeadingData, hidden::HiddenData, output::OutputData, - select::SelectData, spacer::SpacerData, submit::SubmitData, text_area::TextAreaData, - text_input::TextInputData, ControlData, ControlRenderData, +use crate::{ + controls::{ + button::ButtonData, checkbox::CheckboxData, heading::HeadingData, hidden::HiddenData, + output::OutputData, select::SelectData, spacer::SpacerData, submit::SubmitData, + text_area::TextAreaData, text_input::TextInputData, ControlData, ControlRenderData, + }, + FormToolData, }; use leptos::*; use std::rc::Rc; @@ -35,7 +38,7 @@ impl FormStyle for GridFormStyle { ) -> View { // TODO: extract this to a common thing let mut width = 1; - for style in control.style { + for style in control.styles { match style { GridFormStylingAttributes::Width(w) => width = w, } @@ -78,14 +81,10 @@ impl FormStyle for GridFormStyle { .data .options .into_iter() - .map(|value| { - let cloned_value = value.clone(); + .map(|(display, value)| { view! { - } }) @@ -112,9 +111,7 @@ impl FormStyle for GridFormStyle { } fn submit(&self, control: ControlRenderData) -> View { - view! { - - } + view! { } .into_view() } @@ -137,7 +134,8 @@ impl FormStyle for GridFormStyle { on:change=move |ev| { value_setter(event_target_value(&ev)); } - > + > + } @@ -168,7 +166,7 @@ impl FormStyle for GridFormStyle { validation_state: Signal>, ) -> View { let mut width = 1; - for style in control.style { + for style in control.styles { match style { GridFormStylingAttributes::Width(w) => width = w, } @@ -198,6 +196,7 @@ impl FormStyle for GridFormStyle { } } /> +
} @@ -230,7 +229,7 @@ impl FormStyle for GridFormStyle { value_setter: Box::ReturnType)>, ) -> View { let mut width = 1; - for style in control.style { + for style in control.styles { match style { GridFormStylingAttributes::Width(w) => width = w, } @@ -270,7 +269,7 @@ impl FormStyle for GridFormStyle { validation_state: Signal>, ) -> View { let mut width = 1; - for style in control.style { + for style in control.styles { match style { GridFormStylingAttributes::Width(w) => width = w, } @@ -317,7 +316,7 @@ impl FormStyle for GridFormStyle { validation_state: Signal>, ) -> View { let mut width = 1; - for style in control.style { + for style in control.styles { match style { GridFormStylingAttributes::Width(w) => width = w, } @@ -352,27 +351,32 @@ impl FormStyle for GridFormStyle { .into_view() } - fn button( + fn button( &self, - control: ControlRenderData>, + control: ControlRenderData>, + data_signal: RwSignal, ) -> View { let mut width = 1; - for style in control.style { + for style in control.styles { match style { GridFormStylingAttributes::Width(w) => width = w, } } let action = control.data.action.clone(); - let signal = control.data.fd_signal.clone(); let on_click = move |ev: MouseEvent| { if let Some(action) = action.clone() { - signal.update(|fd| action(ev, fd)); + data_signal.update(|fd| action(ev, fd)); } }; view! { - } @@ -398,15 +402,13 @@ impl FormStyle for GridFormStyle { fn spacer(&self, control: ControlRenderData) -> View { let mut width = 12; - for style in control.style { + for style in control.styles { match style { GridFormStylingAttributes::Width(w) => width = w, } } - view! { -
- } + view! {
} .into_view() } } diff --git a/src/styles/mod.rs b/src/styles/mod.rs index 36383f6..68fb6cd 100644 --- a/src/styles/mod.rs +++ b/src/styles/mod.rs @@ -9,7 +9,7 @@ use crate::{ }, FormToolData, }; -use leptos::{Signal, View}; +use leptos::{RwSignal, Signal, View}; pub use grid_form::{GridFormStyle, GridFormStylingAttributes}; @@ -58,7 +58,11 @@ pub trait FormStyle: Default + 'static { value_setter: Box::ReturnType)>, validation_state: Signal>, ) -> View; - fn button(&self, control: ControlRenderData>) -> View; + fn button( + &self, + control: ControlRenderData>, + data_signal: RwSignal, + ) -> View; fn checkbox( &self, control: ControlRenderData,