generated from mitchell/rust_template
add button
This commit is contained in:
parent
9b4bbfdb74
commit
5d0b4a7449
@ -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
55
src/controls/button.rs
Normal 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
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -6,6 +6,7 @@ use crate::controls::{
|
||||
};
|
||||
use leptos::*;
|
||||
use std::rc::Rc;
|
||||
use web_sys::MouseEvent;
|
||||
|
||||
pub enum GridFormStylingAttributes {
|
||||
Width(u32),
|
||||
@ -112,8 +113,10 @@ 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"/> }
|
||||
.into_view()
|
||||
view! {
|
||||
<input type="submit" value=control.data.text class="col-span-full form_button"/>
|
||||
}
|
||||
.into_view()
|
||||
}
|
||||
|
||||
fn text_area(
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@ -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>,
|
||||
|
||||
Reference in New Issue
Block a user