generated from mitchell/rust_template
add button
This commit is contained in:
parent
9b4bbfdb74
commit
5d0b4a7449
@ -69,7 +69,7 @@
|
|||||||
color: #ef4444;
|
color: #ef4444;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form_submit {
|
.form_button {
|
||||||
display: block;
|
display: block;
|
||||||
outline: none;
|
outline: none;
|
||||||
border: none;
|
border: none;
|
||||||
@ -89,7 +89,6 @@
|
|||||||
background-color: #005fb3;
|
background-color: #005fb3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// column widths
|
// column widths
|
||||||
.col-span-full {
|
.col-span-full {
|
||||||
grid-column: 1 / -1;
|
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 leptos::{RwSignal, Signal, View};
|
||||||
use std::{fmt::Display, rc::Rc, str::FromStr};
|
use std::{fmt::Display, rc::Rc, str::FromStr};
|
||||||
|
|
||||||
|
pub mod button;
|
||||||
pub mod checkbox;
|
pub mod checkbox;
|
||||||
pub mod group;
|
pub mod group;
|
||||||
pub mod heading;
|
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.
|
/// This builder allows you to specify what components should make up the form.
|
||||||
pub struct FormBuilder<FD: FormToolData, FS: FormStyle> {
|
pub struct FormBuilder<FD: FormToolData, FS: FormStyle> {
|
||||||
/// The [`ToolFormData`] signal.
|
/// The [`ToolFormData`] signal.
|
||||||
fd: RwSignal<FD>,
|
pub(crate) fd: RwSignal<FD>,
|
||||||
/// The [`FormStyle`].
|
/// The [`FormStyle`].
|
||||||
fs: FS,
|
fs: FS,
|
||||||
/// The list of [`ValidationFn`]s.
|
/// The list of [`ValidationFn`]s.
|
||||||
|
|||||||
@ -6,6 +6,7 @@ use crate::controls::{
|
|||||||
};
|
};
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use web_sys::MouseEvent;
|
||||||
|
|
||||||
pub enum GridFormStylingAttributes {
|
pub enum GridFormStylingAttributes {
|
||||||
Width(u32),
|
Width(u32),
|
||||||
@ -112,8 +113,10 @@ impl FormStyle for GridFormStyle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn submit(&self, control: ControlRenderData<Self, SubmitData>) -> View {
|
fn submit(&self, control: ControlRenderData<Self, SubmitData>) -> View {
|
||||||
view! { <input type="submit" value=control.data.text class="col-span-full form_submit"/> }
|
view! {
|
||||||
.into_view()
|
<input type="submit" value=control.data.text class="col-span-full form_button"/>
|
||||||
|
}
|
||||||
|
.into_view()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn text_area(
|
fn text_area(
|
||||||
@ -353,4 +356,31 @@ impl FormStyle for GridFormStyle {
|
|||||||
fn group(&self, _control: ControlRenderData<Self, crate::controls::group::GroupData>) -> View {
|
fn group(&self, _control: ControlRenderData<Self, crate::controls::group::GroupData>) -> View {
|
||||||
todo!()
|
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;
|
mod grid_form;
|
||||||
pub use grid_form::{GridFormStyle, GridFormStylingAttributes};
|
pub use grid_form::{GridFormStyle, GridFormStylingAttributes};
|
||||||
|
|
||||||
use crate::controls::{
|
use crate::{
|
||||||
checkbox::CheckboxData, group::GroupData, heading::HeadingData, hidden::HiddenData,
|
controls::{
|
||||||
output::OutputData, radio_buttons::RadioButtonsData, select::SelectData, slider::SliderData,
|
button::ButtonData, checkbox::CheckboxData, group::GroupData, heading::HeadingData,
|
||||||
stepper::StepperData, submit::SubmitData, text_area::TextAreaData, text_input::TextInputData,
|
hidden::HiddenData, output::OutputData, radio_buttons::RadioButtonsData,
|
||||||
ControlData, ControlRenderData,
|
select::SelectData, slider::SliderData, stepper::StepperData, submit::SubmitData,
|
||||||
|
text_area::TextAreaData, text_input::TextInputData, ControlData, ControlRenderData,
|
||||||
|
},
|
||||||
|
FormToolData,
|
||||||
};
|
};
|
||||||
use leptos::{Signal, View};
|
use leptos::{Signal, View};
|
||||||
|
|
||||||
@ -54,6 +57,7 @@ pub trait FormStyle: Default + 'static {
|
|||||||
value_setter: Box<dyn Fn(<SelectData as ControlData>::ReturnType)>,
|
value_setter: Box<dyn Fn(<SelectData as ControlData>::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View;
|
) -> View;
|
||||||
|
fn button<FD: FormToolData>(&self, control: ControlRenderData<Self, ButtonData<FD>>) -> View;
|
||||||
fn checkbox(
|
fn checkbox(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, CheckboxData>,
|
control: ControlRenderData<Self, CheckboxData>,
|
||||||
|
|||||||
Reference in New Issue
Block a user