add button

This commit is contained in:
Mitchell Marino 2024-06-07 11:50:21 -05:00
parent 9b4bbfdb74
commit 5d0b4a7449
6 changed files with 99 additions and 10 deletions

View File

@ -69,7 +69,7 @@
color: #ef4444;
}
.form_submit {
.form_button {
display: block;
outline: none;
border: none;
@ -89,7 +89,6 @@
background-color: #005fb3;
}
// column widths
.col-span-full {
grid-column: 1 / -1;

55
src/controls/button.rs Normal file
View File

@ -0,0 +1,55 @@
use super::{ControlRenderData, VanityControlBuilder, VanityControlData};
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
use leptos::{RwSignal, Signal, View};
use std::rc::Rc;
use web_sys::MouseEvent;
#[derive(Clone)]
pub struct ButtonData<FD: FormToolData> {
pub(crate) text: String,
pub(crate) action: Option<Rc<dyn Fn(MouseEvent, &mut FD)>>,
// this will need to be set before calling the build method
pub(crate) fd_signal: RwSignal<FD>,
}
impl<FD: FormToolData> VanityControlData for ButtonData<FD> {
fn build_control<FS: FormStyle>(
fs: &FS,
control: ControlRenderData<FS, Self>,
_value_getter: Option<Signal<String>>,
) -> View {
fs.button(control)
}
}
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
pub fn button(
mut self,
builder: impl Fn(
VanityControlBuilder<FD, FS, ButtonData<FD>>,
) -> VanityControlBuilder<FD, FS, ButtonData<FD>>,
) -> Self {
let data = ButtonData {
text: String::default(),
action: None,
fd_signal: self.fd,
};
let vanity_builder = VanityControlBuilder::new(data);
let control = builder(vanity_builder);
self.add_vanity(control);
self
}
}
impl<FD: FormToolData, FS: FormStyle> VanityControlBuilder<FD, FS, ButtonData<FD>> {
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, &mut FD) + 'static) -> Self {
self.data.action = Some(Rc::new(action));
self
}
}

View File

@ -2,6 +2,7 @@ use crate::{form::FormToolData, styles::FormStyle};
use leptos::{RwSignal, Signal, View};
use std::{fmt::Display, rc::Rc, str::FromStr};
pub mod button;
pub mod checkbox;
pub mod group;
pub mod heading;

View File

@ -21,7 +21,7 @@ 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.
fd: RwSignal<FD>,
pub(crate) fd: RwSignal<FD>,
/// The [`FormStyle`].
fs: FS,
/// The list of [`ValidationFn`]s.

View File

@ -6,6 +6,7 @@ use crate::controls::{
};
use leptos::*;
use std::rc::Rc;
use web_sys::MouseEvent;
pub enum GridFormStylingAttributes {
Width(u32),
@ -112,7 +113,9 @@ impl FormStyle for GridFormStyle {
}
fn submit(&self, control: ControlRenderData<Self, SubmitData>) -> View {
view! { <input type="submit" value=control.data.text class="col-span-full form_submit"/> }
view! {
<input type="submit" value=control.data.text class="col-span-full form_button"/>
}
.into_view()
}
@ -353,4 +356,31 @@ impl FormStyle for GridFormStyle {
fn group(&self, _control: ControlRenderData<Self, crate::controls::group::GroupData>) -> View {
todo!()
}
fn button<FD: crate::FormToolData>(
&self,
control: ControlRenderData<Self, crate::controls::button::ButtonData<FD>>,
) -> View {
let mut width = 1;
for style in control.style {
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));
}
};
view! {
<button type="button" class="form_button" on:click=on_click style:grid-column=format!("span {}", width) class="form_button">
{control.data.text}
</button>
}
.into_view()
}
}

View File

@ -1,11 +1,14 @@
mod grid_form;
pub use grid_form::{GridFormStyle, GridFormStylingAttributes};
use crate::controls::{
checkbox::CheckboxData, group::GroupData, heading::HeadingData, hidden::HiddenData,
output::OutputData, radio_buttons::RadioButtonsData, select::SelectData, slider::SliderData,
stepper::StepperData, submit::SubmitData, text_area::TextAreaData, text_input::TextInputData,
ControlData, ControlRenderData,
use crate::{
controls::{
button::ButtonData, checkbox::CheckboxData, group::GroupData, heading::HeadingData,
hidden::HiddenData, output::OutputData, radio_buttons::RadioButtonsData,
select::SelectData, slider::SliderData, stepper::StepperData, submit::SubmitData,
text_area::TextAreaData, text_input::TextInputData, ControlData, ControlRenderData,
},
FormToolData,
};
use leptos::{Signal, View};
@ -54,6 +57,7 @@ pub trait FormStyle: Default + 'static {
value_setter: Box<dyn Fn(<SelectData as ControlData>::ReturnType)>,
validation_state: Signal<Result<(), String>>,
) -> View;
fn button<FD: FormToolData>(&self, control: ControlRenderData<Self, ButtonData<FD>>) -> View;
fn checkbox(
&self,
control: ControlRenderData<Self, CheckboxData>,