add spacer

This commit is contained in:
Mitchell Marino 2024-06-10 13:54:37 -05:00
parent e7fd8ec7e1
commit 1dc676cc37
6 changed files with 92 additions and 8 deletions

22
src/controls/custom.rs Normal file
View File

@ -0,0 +1,22 @@
use super::{ControlBuilder, ControlData};
use crate::{styles::FormStyle, FormBuilder, FormToolData};
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
pub fn custom<CC: ControlData, FDT: Clone + PartialEq + 'static>(
mut self,
control_data: CC,
builder: impl Fn(ControlBuilder<FD, FS, CC, FDT>) -> ControlBuilder<FD, FS, CC, FDT>,
) -> Self {
let control_builder = ControlBuilder::new(control_data);
let control = builder(control_builder);
self.add_control(control);
self
}
pub fn custom_default<CC: Default + ControlData, FDT: Clone + PartialEq + 'static>(
self,
builder: impl Fn(ControlBuilder<FD, FS, CC, FDT>) -> ControlBuilder<FD, FS, CC, FDT>,
) -> Self {
self.new_control(builder)
}
}

View File

@ -4,6 +4,7 @@ use std::{fmt::Display, rc::Rc, str::FromStr};
pub mod button;
pub mod checkbox;
pub mod custom;
pub mod group;
pub mod heading;
pub mod hidden;
@ -11,6 +12,7 @@ pub mod output;
pub mod radio_buttons;
pub mod select;
pub mod slider;
pub mod spacer;
pub mod stepper;
pub mod submit;
pub mod text_area;
@ -52,6 +54,7 @@ pub trait GetterVanityControlData: VanityControlData {}
/// A trait for the data needed to render an interactive control.
pub trait ControlData: 'static {
/// This is the data type returned by this control.
type ReturnType: Clone;
/// Builds the control, returning the [`View`] that was built.
@ -103,6 +106,12 @@ impl<FD: FormToolData, FS: FormStyle, C: VanityControlData> VanityControlBuilder
getter: self.getter,
}
}
/// Adds a styling attribute to this control.
pub fn style(mut self, attribute: FS::StylingAttributes) -> Self {
self.style_attributes.push(attribute);
self
}
}
impl<FD: FormToolData, FS: FormStyle, C: GetterVanityControlData> VanityControlBuilder<FD, FS, C> {
@ -159,7 +168,7 @@ pub struct ControlBuilder<FD: FormToolData, FS: FormStyle, C: ControlData, FDT>
pub(crate) unparse_fn: Option<Box<dyn UnparseFn<C::ReturnType, FDT>>>,
pub(crate) validation_fn: Option<Rc<dyn ValidationFn<FD>>>,
pub(crate) style_attributes: Vec<FS::StylingAttributes>,
pub(crate) data: C,
pub data: C,
}
impl<FD: FormToolData, FS: FormStyle, C: ControlData, FDT> ControlBuilder<FD, FS, C, FDT> {
@ -312,7 +321,7 @@ where
/// The parse and unparse functions define how to turn what the user
/// types in the form into what is stored in the form data struct and
/// vice versa.
pub fn parse_trimmed_string(mut self) -> Self {
pub fn parse_trimmed(mut self) -> Self {
self.parse_fn = Some(Box::new(|control_return_value| {
control_return_value
.trim()

37
src/controls/spacer.rs Normal file
View File

@ -0,0 +1,37 @@
use leptos::{prelude::Signal, View};
use super::{ControlRenderData, VanityControlBuilder, VanityControlData};
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct SpacerData {
pub(crate) height: Option<String>,
}
impl VanityControlData for SpacerData {
fn build_control<FS: FormStyle>(
fs: &FS,
control: ControlRenderData<FS, Self>,
_value_getter: Option<Signal<String>>,
) -> View {
fs.spacer(control)
}
}
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
pub fn spacer(
self,
builder: impl Fn(
VanityControlBuilder<FD, FS, SpacerData>,
) -> VanityControlBuilder<FD, FS, SpacerData>,
) -> Self {
self.new_vanity(builder)
}
}
impl<FD: FormToolData, FS: FormStyle> VanityControlBuilder<FD, FS, SpacerData> {
pub fn height(mut self, height: impl ToString) -> Self {
self.data.height = Some(height.to_string());
self
}
}

View File

@ -1,4 +1,4 @@
use leptos::View;
use leptos::{prelude::Signal, View};
use super::{ControlRenderData, VanityControlBuilder, VanityControlData};
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
@ -12,7 +12,7 @@ impl VanityControlData for SubmitData {
fn build_control<FS: FormStyle>(
fs: &FS,
control: ControlRenderData<FS, Self>,
_value_getter: Option<leptos::prelude::Signal<String>>,
_value_getter: Option<Signal<String>>,
) -> View {
fs.submit(control)
}

View File

@ -1,8 +1,8 @@
use super::FormStyle;
use crate::controls::{
checkbox::CheckboxData, heading::HeadingData, hidden::HiddenData, output::OutputData,
select::SelectData, submit::SubmitData, text_area::TextAreaData, text_input::TextInputData,
ControlData, ControlRenderData,
select::SelectData, spacer::SpacerData, submit::SubmitData, text_area::TextAreaData,
text_input::TextInputData, ControlData, ControlRenderData,
};
use leptos::*;
use std::rc::Rc;
@ -395,4 +395,18 @@ impl FormStyle for GridFormStyle {
}
.into_view()
}
fn spacer(&self, control: ControlRenderData<Self, SpacerData>) -> View {
let mut width = 12;
for style in control.style {
match style {
GridFormStylingAttributes::Width(w) => width = w,
}
}
view! {
<div style:grid-column=format!("span {}", width) style:height=control.data.height/>
}
.into_view()
}
}

View File

@ -1,10 +1,11 @@
mod grid_form;
use crate::{
controls::{
button::ButtonData, checkbox::CheckboxData, 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,
slider::SliderData, spacer::SpacerData, stepper::StepperData, submit::SubmitData,
text_area::TextAreaData, text_input::TextInputData, ControlData, ControlRenderData,
},
FormToolData,
};
@ -87,4 +88,5 @@ pub trait FormStyle: Default + 'static {
// TODO: test custom component
fn custom_component(&self, view: View) -> View;
fn group(&self, inner: View, style: Vec<Self::StylingAttributes>) -> View;
fn spacer(&self, control: ControlRenderData<Self, SpacerData>) -> View;
}