This repository has been archived on 2024-08-06. You can view files and clone it, but cannot push or open issues or pull requests.
leptos_form_tool/src/styles/grid_form.rs

156 lines
4.6 KiB
Rust

use super::FormStyle;
use crate::controls::{
heading::HeadingData, select::SelectData, submit::SubmitData, text_area::TextAreaData,
text_input::TextInputData, ControlData, ControlRenderData,
};
use leptos::*;
use leptos_router::Form;
pub enum GridFormStylingAttributes {
Width(u32),
}
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct GridFormStyle;
impl FormStyle for GridFormStyle {
type StylingAttributes = GridFormStylingAttributes;
// TODO: something about an on-submit thing
fn form_frame(&self, children: View) -> View {
view! {
<Form action="" class="form_grid">
{children}
</Form>
}
.into_view()
}
fn heading(&self, control: ControlRenderData<Self, HeadingData>) -> View {
view! {
<h2 class="form_heading">
{&control.data.title}
</h2>
}
.into_view()
}
fn text_input(
&self,
control: ControlRenderData<Self, TextInputData>,
value_getter: Signal<<TextInputData as ControlData>::ReturnType>,
value_setter: Box<dyn Fn(<TextInputData as ControlData>::ReturnType)>,
validation_state: Signal<Result<(), String>>,
) -> View {
view! {
<div>
<div>
<label for={&control.data.name} class="form_label">
{control.data.label.as_ref()}
</label>
<span class="form_error">
{move || format!("{}", validation_state.get().err().unwrap_or_default())}
</span>
</div>
<input
// TODO:
type=control.data.input_type
id=&control.data.name
name=control.data.name
placeholder=control.data.placeholder
prop:value=move || value_getter.get()
on:change=move |ev| {
value_setter(event_target_value(&ev));
}
class="form_input"
class=("form_input_invalid", move || validation_state.get().is_err())
/>
</div>
}
.into_view()
}
fn select(
&self,
control: ControlRenderData<Self, SelectData>,
value_getter: Signal<<SelectData as ControlData>::ReturnType>,
value_setter: Box<dyn Fn(<SelectData as ControlData>::ReturnType)>,
validation_state: Signal<Result<(), String>>,
) -> View {
let options_view = control
.data
.options
.into_iter()
.map(|value| {
// let value = value;
let cloned_value = value.clone();
view! {
<option
value={value}
selected=move || value_getter.get() == *cloned_value
>
*value
</option>
}
})
.collect_view();
view! {
<div>
{move || format!("{:?}", validation_state.get())}
<select
id=&control.data.name
name=control.data.name
class="form_input"
on:change=move |ev| {
value_setter(event_target_value(&ev));
}
>
{options_view}
</select>
</div>
}
.into_view()
}
fn submit(&self, control: ControlRenderData<Self, SubmitData>) -> View {
view! {
<input
type="submit"
value=control.data.text
class="w-full form_submit"
/>
}
.into_view()
}
fn text_area(
&self,
control: ControlRenderData<Self, TextAreaData>,
value_getter: Signal<<TextAreaData as ControlData>::ReturnType>,
value_setter: Box<dyn Fn(<TextAreaData as ControlData>::ReturnType)>,
validation_state: Signal<Result<(), String>>,
) -> View {
view! {
<div>
{move || format!("{:?}", validation_state.get())}
<textarea
id=&control.data.name
name=control.data.name
placeholder=control.data.placeholder
class="form_input"
prop:value=move || value_getter.get()
on:change=move |ev| {
value_setter(event_target_value(&ev));
}
/>
</div>
}
.into_view()
}
fn custom_component(&self, view: View) -> View {
view
}
}