use super::{BuilderFn, ControlRenderData, ShowWhenFn}; use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle}; use leptos::view; use leptos::RwSignal; use leptos::Show; use leptos::Signal; use std::rc::Rc; use web_sys::MouseEvent; type ButtonAction = dyn Fn(MouseEvent, RwSignal) + 'static; pub struct ButtonData { pub text: String, pub action: Option>>, } impl Default for ButtonData { fn default() -> Self { ButtonData { text: String::default(), action: None, } } } impl Clone for ButtonData { fn clone(&self) -> Self { ButtonData { text: self.text.clone(), action: self.action.clone(), } } } impl FormBuilder { pub fn button(mut self, builder: impl BuilderFn, FD::Context>) -> Self { let button_builder = ButtonBuilder::new(); let control = builder(button_builder, self.cx.clone()); let render_data = ControlRenderData { data: control.data, styles: control.styles, }; let show_when = control.show_when; let cx = self.cx.clone(); let render_fn = move |fs: Rc, fd: RwSignal| { let render_data = Rc::new(render_data); // let cloned_fs = fs.clone(); let view = move || fs.clone().button(render_data.clone(), fd); let view = match show_when { Some(when) => { let when = move || when(fd.into(), cx.clone()); view! { {view.clone()} } } None => view(), }; (view, None) }; self.render_fns.push(Box::new(render_fn)); self } } pub struct ButtonBuilder { pub(crate) styles: Vec<::StylingAttributes>, pub(crate) data: ButtonData, pub(crate) show_when: Option>>, } impl ButtonBuilder { fn new() -> Self { ButtonBuilder { styles: Vec::default(), data: ButtonData::default(), show_when: None, } } /// Sets the function to decide when to render the control. /// /// Validations for components that are not shown DO NOT run. pub fn show_when( mut self, when: impl Fn(Signal, Rc) -> bool + 'static, ) -> Self { self.show_when = Some(Box::new(when)); self } pub fn style(mut self, style: ::StylingAttributes) -> Self { self.styles.push(style); self } pub fn text(mut self, text: impl ToString) -> Self { self.data.text = text.to_string(); self } pub fn action(mut self, action: impl Fn(MouseEvent, RwSignal) + 'static) -> Self { self.data.action = Some(Rc::new(action)); self } }