This repository has been archived on 2024-08-06. You can view files and clone it, but cannot push or open issues or pull requests.
leptos_form_tool/src/controls/button.rs
2024-06-18 13:10:49 -05:00

109 lines
3.1 KiB
Rust

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<FD> = dyn Fn(MouseEvent, RwSignal<FD>) + 'static;
pub struct ButtonData<FD: FormToolData> {
pub text: String,
pub action: Option<Rc<ButtonAction<FD>>>,
}
impl<FD: FormToolData> Default for ButtonData<FD> {
fn default() -> Self {
ButtonData {
text: String::default(),
action: None,
}
}
}
impl<FD: FormToolData> Clone for ButtonData<FD> {
fn clone(&self) -> Self {
ButtonData {
text: self.text.clone(),
action: self.action.clone(),
}
}
}
impl<FD: FormToolData> FormBuilder<FD> {
pub fn button(mut self, builder: impl BuilderFn<ButtonBuilder<FD>, 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::Style>, fd: RwSignal<FD>| {
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! {
<Show when=when>
{view.clone()}
</Show>
}
}
None => view(),
};
(view, None)
};
self.render_fns.push(Box::new(render_fn));
self
}
}
pub struct ButtonBuilder<FD: FormToolData> {
pub(crate) styles: Vec<<FD::Style as FormStyle>::StylingAttributes>,
pub(crate) data: ButtonData<FD>,
pub(crate) show_when: Option<Box<dyn ShowWhenFn<FD, FD::Context>>>,
}
impl<FD: FormToolData> ButtonBuilder<FD> {
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<FD>, Rc<FD::Context>) -> bool + 'static,
) -> Self {
self.show_when = Some(Box::new(when));
self
}
pub fn style(mut self, style: <FD::Style as FormStyle>::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<FD>) + 'static) -> Self {
self.data.action = Some(Rc::new(action));
self
}
}