remove fd and fs from builder

This commit is contained in:
Mitchell Marino 2024-06-12 16:02:43 -05:00
parent a39f2ce664
commit 115ff1abde
5 changed files with 31 additions and 35 deletions

View File

@ -4,11 +4,19 @@ use leptos::RwSignal;
use std::rc::Rc;
use web_sys::MouseEvent;
#[derive(Default, Clone)]
#[derive(Clone)]
pub struct ButtonData<FD: FormToolData> {
pub(crate) text: String,
pub(crate) action: Option<Rc<dyn Fn(MouseEvent, &mut FD)>>,
}
impl<FD: FormToolData> Default for ButtonData<FD> {
fn default() -> Self {
ButtonData {
text: String::default(),
action: None,
}
}
}
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
pub fn button(

View File

@ -4,9 +4,8 @@ use leptos::{CollectView, RwSignal};
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
pub fn group(mut self, builder: impl Fn(FormBuilder<FD, FS>) -> FormBuilder<FD, FS>) -> Self {
let mut group_builder = FormBuilder::new_group(self.fd, self.fs);
let mut group_builder = FormBuilder::new();
group_builder = builder(group_builder);
self.fs = group_builder.fs; // take the style back
for validation in group_builder.validations {
self.validations.push(validation);

View File

@ -78,7 +78,7 @@ impl<FD: FormToolData> IntoView for Form<FD> {
///
/// This trait defines a function that can be used to build all the data needed
/// to physically lay out a form, and how that data should be parsed and validated.
pub trait FormToolData: Default + Clone + 'static {
pub trait FormToolData: Clone + 'static {
type Style: FormStyle;
/// Defines how the form should be layed out and how the data should be parsed and validated.
@ -97,9 +97,9 @@ pub trait FormToolData: Default + Clone + 'static {
/// component. Call [`get_action_form`]\() to get the
/// [`ActionForm`](leptos_router::ActionForm) version.
fn get_form(self, action: impl ToString, style: Self::Style) -> Form<Self> {
let builder = FormBuilder::new(self, style);
let builder = FormBuilder::new();
let builder = Self::build_form(builder);
builder.build_plain_form(action.to_string())
builder.build_plain_form(action.to_string(), self, style)
}
/// Constructs a [`Form`] for this [`FormToolData`] type.
@ -118,9 +118,9 @@ pub trait FormToolData: Default + Clone + 'static {
<<ServFn::Client as Client<ServFn::Error>>::Request as ClientReq<ServFn::Error>>::FormData:
From<FormData>,
{
let builder = FormBuilder::new(self, style);
let builder = FormBuilder::new();
let builder = Self::build_form(builder);
builder.build_action_form(action)
builder.build_action_form(action, self, style)
}
/// Gets a [`Validator`] for this [`ToolFormData`].
@ -132,7 +132,7 @@ pub trait FormToolData: Default + Clone + 'static {
/// However, the code to render the views are not configured out, it
/// simply doesn't run, so the view needs to compile even on the server.
fn get_validator() -> FormValidator<Self> {
let builder = FormBuilder::new(Self::default(), Self::Style::default());
let builder = FormBuilder::new();
let builder = Self::build_form(builder);
builder.validator()
}

View File

@ -20,10 +20,6 @@ use web_sys::{FormData, SubmitEvent};
///
/// This builder allows you to specify what components should make up the form.
pub struct FormBuilder<FD: FormToolData, FS: FormStyle> {
/// The [`ToolFormData`] signal.
pub(crate) fd: RwSignal<FD>,
/// The [`FormStyle`].
pub(crate) fs: FS,
/// The list of [`ValidationFn`]s.
pub(crate) validations: Vec<Rc<dyn ValidationFn<FD>>>,
/// The list of functions that will render the form.
@ -34,21 +30,8 @@ pub struct FormBuilder<FD: FormToolData, FS: FormStyle> {
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
/// Creates a new [`FormBuilder`]
pub(crate) fn new(starting_data: FD, form_style: FS) -> FormBuilder<FD, FS> {
let fd = create_rw_signal(starting_data);
pub(crate) fn new() -> FormBuilder<FD, FS> {
FormBuilder {
fd,
fs: form_style,
validations: Vec::new(),
render_fns: Vec::new(),
styles: Vec::new(),
}
}
pub(crate) fn new_group(fd: RwSignal<FD>, fs: FS) -> FormBuilder<FD, FS> {
FormBuilder {
fd,
fs,
validations: Vec::new(),
render_fns: Vec::new(),
styles: Vec::new(),
@ -232,19 +215,23 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
pub(crate) fn build_action_form<ServFn>(
self,
action: Action<ServFn, Result<ServFn::Output, ServerFnError<ServFn::Error>>>,
fd: FD,
fs: FS,
) -> Form<FD>
where
ServFn: DeserializeOwned + ServerFn<InputEncoding = PostUrl> + 'static,
<<ServFn::Client as Client<ServFn::Error>>::Request as ClientReq<ServFn::Error>>::FormData:
From<FormData>,
{
let fd = create_rw_signal(fd);
let (views, validation_cbs): (Vec<_>, Vec<_>) = self
.render_fns
.into_iter()
.map(|r_fn| r_fn(&self.fs, self.fd))
.map(|r_fn| r_fn(&fs, fd))
.unzip();
let elements = self.fs.form_frame(views.into_view(), self.styles);
let elements = fs.form_frame(views.into_view(), self.styles);
let on_submit = move |ev: SubmitEvent| {
let mut failed = false;
@ -265,20 +252,22 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
};
Form {
fd: self.fd,
fd,
validations: self.validations,
view,
}
}
pub(crate) fn build_plain_form(self, url: String) -> Form<FD> {
pub(crate) fn build_plain_form(self, url: String, fd: FD, fs: FS) -> Form<FD> {
let fd = create_rw_signal(fd);
let (views, validation_cbs): (Vec<_>, Vec<_>) = self
.render_fns
.into_iter()
.map(|r_fn| r_fn(&self.fs, self.fd))
.map(|r_fn| r_fn(&fs, fd))
.unzip();
let elements = self.fs.form_frame(views.into_view(), self.styles);
let elements = fs.form_frame(views.into_view(), self.styles);
let on_submit = move |ev: SubmitEvent| {
let mut failed = false;
@ -299,7 +288,7 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
};
Form {
fd: self.fd,
fd,
validations: self.validations,
view,
}

View File

@ -13,7 +13,7 @@ use leptos::{RwSignal, Signal, View};
pub use grid_form::{GridFormStyle, GridFormStylingAttributes};
pub trait FormStyle: Default + 'static {
pub trait FormStyle: 'static {
type StylingAttributes;
/// Render any containing components for the form.