diff --git a/Cargo.toml b/Cargo.toml index ca428b9..93e0945 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,6 @@ name = "leptos_form_tool" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] +leptos = "0.6.9" diff --git a/src/controls/heading.rs b/src/controls/heading.rs new file mode 100644 index 0000000..bba7f1a --- /dev/null +++ b/src/controls/heading.rs @@ -0,0 +1,30 @@ +use leptos::View; + +use crate::{ControlBuilder, ControlData, FormBuilder, FormData, FormStyleProvider}; + +pub struct HeadingData { + pub(crate) title: String, +} + +impl HeadingData { + fn new(title: String) -> Self { + HeadingData { title } + } +} + +impl ControlData for HeadingData { + fn build_control(self, fs: &FS, attributes: Vec) -> View { + fs.heading(self, attributes) + } +} + +impl FormBuilder { + pub fn heading(self, title: impl ToString) -> ControlBuilder { + ControlBuilder { + fb: self, + parse_fn: None, + style_attributes: Vec::new(), + data: HeadingData::new(title.to_string()), + } + } +} diff --git a/src/controls/mod.rs b/src/controls/mod.rs new file mode 100644 index 0000000..959d1ae --- /dev/null +++ b/src/controls/mod.rs @@ -0,0 +1,5 @@ +pub mod heading; +pub mod select; +pub mod submit; +pub mod text_area; +pub mod text_input; diff --git a/src/controls/select.rs b/src/controls/select.rs new file mode 100644 index 0000000..4612b4d --- /dev/null +++ b/src/controls/select.rs @@ -0,0 +1,41 @@ +use leptos::View; + +use crate::{ControlBuilder, ControlData, FormBuilder, FormData, FormStyleProvider}; + +pub struct SelectData { + pub(crate) name: String, + pub(crate) options: Vec, +} + +impl SelectData { + fn new(name: String) -> Self { + SelectData { + name, + options: Vec::new(), + } + } +} + +impl ControlData for SelectData { + fn build_control(self, fs: &FS, attributes: Vec) -> View { + fs.select(self, attributes) + } +} + +impl FormBuilder { + pub fn select(self, name: impl ToString) -> ControlBuilder { + ControlBuilder { + fb: self, + parse_fn: None, + style_attributes: Vec::new(), + data: SelectData::new(name.to_string()), + } + } +} + +impl ControlBuilder { + pub fn options(mut self, options: Vec) -> Self { + self.data.options = options; + self + } +} diff --git a/src/controls/submit.rs b/src/controls/submit.rs new file mode 100644 index 0000000..dd1330b --- /dev/null +++ b/src/controls/submit.rs @@ -0,0 +1,30 @@ +use leptos::View; + +use crate::{ControlBuilder, ControlData, FormBuilder, FormData, FormStyleProvider}; + +pub struct SubmitData { + pub(crate) text: String, +} + +impl SubmitData { + fn new(text: String) -> Self { + SubmitData { text } + } +} + +impl ControlData for SubmitData { + fn build_control(self, fs: &FS, attributes: Vec) -> View { + fs.submit(self, attributes) + } +} + +impl FormBuilder { + pub fn submit(self, text: impl ToString) -> ControlBuilder { + ControlBuilder { + fb: self, + parse_fn: None, + style_attributes: Vec::new(), + data: SubmitData::new(text.to_string()), + } + } +} diff --git a/src/controls/text_area.rs b/src/controls/text_area.rs new file mode 100644 index 0000000..5684c9e --- /dev/null +++ b/src/controls/text_area.rs @@ -0,0 +1,41 @@ +use leptos::View; + +use crate::{ControlBuilder, ControlData, FormBuilder, FormData, FormStyleProvider}; + +pub struct TextAreaData { + pub(crate) name: String, + pub(crate) placeholder: Option, +} + +impl TextAreaData { + fn new(name: String) -> Self { + TextAreaData { + name, + placeholder: None, + } + } +} + +impl ControlData for TextAreaData { + fn build_control(self, fs: &FS, attributes: Vec) -> View { + fs.text_area(self, attributes) + } +} + +impl FormBuilder { + pub fn text_area(self, name: impl ToString) -> ControlBuilder { + ControlBuilder { + fb: self, + parse_fn: None, + style_attributes: Vec::new(), + data: TextAreaData::new(name.to_string()), + } + } +} + +impl ControlBuilder { + pub fn placeholder(mut self, placeholder: impl ToString) -> Self { + self.data.placeholder = Some(placeholder.to_string()); + self + } +} diff --git a/src/controls/text_input.rs b/src/controls/text_input.rs new file mode 100644 index 0000000..f05f3b5 --- /dev/null +++ b/src/controls/text_input.rs @@ -0,0 +1,62 @@ +use leptos::View; + +use crate::{ControlBuilder, ControlData, FormBuilder, FormData, FormStyleProvider}; + +pub struct TextInputData { + pub(crate) name: String, + pub(crate) placeholder: Option, + pub(crate) label: Option, + pub(crate) initital_text: String, + pub(crate) input_type: &'static str, +} + +impl TextInputData { + fn new(name: String) -> Self { + TextInputData { + name, + placeholder: None, + label: None, + initital_text: String::new(), + input_type: "input", + } + } +} + +impl ControlData for TextInputData { + fn build_control(self, fs: &FS, attributes: Vec) -> View { + fs.text_input(self, attributes) + } +} + +impl FormBuilder { + pub fn text_input(self, name: impl ToString) -> ControlBuilder { + ControlBuilder { + fb: self, + parse_fn: None, + style_attributes: Vec::new(), + data: TextInputData::new(name.to_string()), + } + } +} + +impl ControlBuilder { + pub fn placeholder(mut self, placeholder: impl ToString) -> Self { + self.data.placeholder = Some(placeholder.to_string()); + self + } + + pub fn label(mut self, label: impl ToString) -> Self { + self.data.label = Some(label.to_string()); + self + } + + pub fn initial_text(mut self, text: impl ToString) -> Self { + self.data.initital_text = text.to_string(); + self + } + + pub fn password(mut self) -> Self { + self.data.input_type = "password"; + self + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..2659700 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,59 @@ +use controls::{ + heading::HeadingData, select::SelectData, submit::SubmitData, text_area::TextAreaData, + text_input::TextInputData, +}; +use leptos::*; +use std::marker::PhantomData; + +mod controls; +mod provider_impl; + +pub trait FormStyleProvider { + type StylingAttributes; + + fn heading(&self, data: HeadingData, attributes: Vec) -> View; + fn text_input(&self, data: TextInputData, attributes: Vec) -> View; + fn select(&self, data: SelectData, attributes: Vec) -> View; + fn submit(&self, data: SubmitData, attributes: Vec) -> View; + fn text_area(&self, data: TextAreaData, attributes: Vec) -> View; + fn custom_component(&self, component: View) -> View; + // TODO: add group +} + +pub trait ControlData: 'static { + fn build_control(self, fs: &FS, attributes: Vec) -> View; +} + +pub struct FormBuilder { + _fd: PhantomData, + fs: FS, + controls: Vec<(Box>, Vec)>, +} + +pub trait FormData {} + +pub struct ControlBuilder> { + fb: FormBuilder, + parse_fn: Option>, + style_attributes: Vec, + data: C, +} + +impl> ControlBuilder { + pub fn parse_fn(mut self, parse_fn: Box) -> Self { + self.parse_fn = Some(parse_fn); + self + } + + pub fn style(mut self, attribute: FS::StylingAttributes) -> Self { + self.style_attributes.push(attribute); + self + } + + pub fn end(mut self) -> FormBuilder { + self.fb + .controls + .push((Box::new(self.data), self.style_attributes)); + self.fb + } +} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/src/provider_impl.rs b/src/provider_impl.rs new file mode 100644 index 0000000..4c7b95a --- /dev/null +++ b/src/provider_impl.rs @@ -0,0 +1,86 @@ +use crate::{ + controls::{select::SelectData, submit::SubmitData, text_area::TextAreaData}, + FormStyleProvider, HeadingData, TextInputData, +}; +use leptos::*; + +pub enum TailwindStylingAttibutes { + Width(u32), +} + +pub struct TailwindFormStyleProvider; + +impl FormStyleProvider for TailwindFormStyleProvider { + type StylingAttributes = TailwindFormStyleProvider; + + // fn label(&self, data: LabelData) -> View { + // view! { + // }.into_view() + // } + + fn heading(&self, data: HeadingData, attributes: Vec) -> View { + view! { +

+ {&data.title} +

+ } + .into_view() + } + + fn text_input(&self, data: TextInputData, attributes: Vec) -> View { + view! { + + + }.into_view() + } + + fn select(&self, data: SelectData, attributes: Vec) -> View { + view! { + + }.into_view() + } + + fn submit(&self, data: SubmitData, attributes: Vec) -> View { + view! { + + } + .into_view() + } + + fn text_area(&self, data: TextAreaData, attributes: Vec) -> View { + view! { +