mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
started porting router to #[component]
This commit is contained in:
parent
422233eecf
commit
ce9aec2520
2 changed files with 45 additions and 71 deletions
|
@ -5,62 +5,43 @@ use typed_builder::TypedBuilder;
|
|||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
|
||||
/// Properties that can be passed to the [Form] component, which is an HTML
|
||||
/// [`form`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form)
|
||||
/// progressively enhanced to use client-side routing.
|
||||
#[derive(TypedBuilder)]
|
||||
pub struct FormProps<A>
|
||||
where
|
||||
A: ToHref + 'static,
|
||||
{
|
||||
/// An HTML [`form`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) progressively
|
||||
/// enhanced to use client-side routing.
|
||||
#[component]
|
||||
pub fn Form<A>(
|
||||
cx: Scope,
|
||||
/// [`method`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-method)
|
||||
/// is the HTTP method to submit the form with (`get` or `post`).
|
||||
#[builder(default, setter(strip_option))]
|
||||
pub method: Option<&'static str>,
|
||||
#[prop(optional)]
|
||||
method: Option<&'static str>,
|
||||
/// [`action`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-action)
|
||||
/// is the URL that processes the form submission. Takes a [String], [&str], or a reactive
|
||||
/// function that returns a [String].
|
||||
pub action: A,
|
||||
action: A,
|
||||
/// [`enctype`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-enctype)
|
||||
/// is the MIME type of the form submission if `method` is `post`.
|
||||
#[builder(default, setter(strip_option))]
|
||||
pub enctype: Option<String>,
|
||||
#[prop(optional)]
|
||||
enctype: Option<String>,
|
||||
/// A signal that will be incremented whenever the form is submitted with `post`. This can useful
|
||||
/// for reactively updating a [Resource] or another signal whenever the form has been submitted.
|
||||
#[builder(default, setter(strip_option))]
|
||||
pub version: Option<RwSignal<usize>>,
|
||||
#[prop(optional)]
|
||||
version: Option<RwSignal<usize>>,
|
||||
/// A signal that will be set if the form submission ends in an error.
|
||||
#[builder(default, setter(strip_option))]
|
||||
pub error: Option<RwSignal<Option<Box<dyn Error>>>>,
|
||||
#[prop(optional)]
|
||||
error: Option<RwSignal<Option<Box<dyn Error>>>>,
|
||||
/// A callback will be called with the [FormData](web_sys::FormData) when the form is submitted.
|
||||
#[builder(default, setter(strip_option))]
|
||||
pub on_form_data: Option<Rc<dyn Fn(&web_sys::FormData)>>,
|
||||
#[prop(optional)]
|
||||
on_form_data: Option<Rc<dyn Fn(&web_sys::FormData)>>,
|
||||
/// A callback will be called with the [Response](web_sys::Response) the server sends in response
|
||||
/// to a form submission.
|
||||
#[builder(default, setter(strip_option))]
|
||||
pub on_response: Option<Rc<dyn Fn(&web_sys::Response)>>,
|
||||
#[prop(optional)]
|
||||
on_response: Option<Rc<dyn Fn(&web_sys::Response)>>,
|
||||
/// Component children; should include the HTML of the form elements.
|
||||
pub children: Box<dyn Fn(Scope) -> Fragment>,
|
||||
}
|
||||
|
||||
/// An HTML [`form`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) progressively
|
||||
/// enhanced to use client-side routing.
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Form<A>(cx: Scope, props: FormProps<A>) -> impl IntoView
|
||||
children: Box<dyn Fn(Scope) -> Fragment>,
|
||||
) -> impl IntoView
|
||||
where
|
||||
A: ToHref + 'static,
|
||||
{
|
||||
let FormProps {
|
||||
method,
|
||||
action,
|
||||
enctype,
|
||||
children,
|
||||
version,
|
||||
error,
|
||||
on_form_data,
|
||||
on_response,
|
||||
} = props;
|
||||
|
||||
let action_version = version;
|
||||
let action = use_resolved_path(cx, move || action.to_href()());
|
||||
|
||||
|
@ -131,18 +112,16 @@ where
|
|||
|
||||
let method = method.unwrap_or("get");
|
||||
|
||||
Component::new("Form", move |cx| {
|
||||
view! { cx,
|
||||
<form
|
||||
method=method
|
||||
action=move || action.get()
|
||||
enctype=enctype
|
||||
on:submit=on_submit
|
||||
>
|
||||
{move || children(cx)}
|
||||
</form>
|
||||
}
|
||||
})
|
||||
view! { cx,
|
||||
<form
|
||||
method=method
|
||||
action=move || action.get()
|
||||
enctype=enctype
|
||||
on:submit=on_submit
|
||||
>
|
||||
{move || children(cx)}
|
||||
</form>
|
||||
}
|
||||
}
|
||||
|
||||
/// Properties that can be passed to the [ActionForm] component, which
|
||||
|
|
|
@ -19,32 +19,27 @@ use crate::{
|
|||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::{unescape, Url};
|
||||
|
||||
/// Props for the [Router] component, which sets up client-side and server-side routing.
|
||||
#[derive(TypedBuilder)]
|
||||
pub struct RouterProps {
|
||||
/// Provides for client-side and server-side routing. This should usually be somewhere near
|
||||
/// the root of the application.
|
||||
#[component]
|
||||
pub fn Router(
|
||||
cx: Scope,
|
||||
/// The base URL for the router. Defaults to "".
|
||||
#[builder(default, setter(strip_option))]
|
||||
pub base: Option<&'static str>,
|
||||
#[builder(default, setter(strip_option))]
|
||||
#[prop(optional)]
|
||||
base: Option<&'static str>,
|
||||
/// A fallback that should be shown if no route is matched.
|
||||
pub fallback: Option<fn() -> View>,
|
||||
#[prop(optional)]
|
||||
fallback: Option<fn() -> View>,
|
||||
/// The `<Router/>` should usually wrap your whole page. It can contain
|
||||
/// any elements, and should include a [Routes](crate::Routes) component somewhere
|
||||
/// to define and display [Route](crate::Route)s.
|
||||
pub children: Box<dyn Fn(Scope) -> Fragment>,
|
||||
}
|
||||
children: Box<dyn Fn(Scope) -> Fragment>,
|
||||
) -> impl IntoView {
|
||||
// create a new RouterContext and provide it to every component beneath the router
|
||||
let router = RouterContext::new(cx, base, fallback);
|
||||
provide_context(cx, router);
|
||||
|
||||
/// Provides for client-side and server-side routing. This should usually be somewhere near
|
||||
/// the root of the application.
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Router(cx: Scope, props: RouterProps) -> impl IntoView {
|
||||
Component::new("Router", move |cx| {
|
||||
// create a new RouterContext and provide it to every component beneath the router
|
||||
let router = RouterContext::new(cx, props.base, props.fallback);
|
||||
provide_context(cx, router);
|
||||
|
||||
move || (props.children)(cx)
|
||||
})
|
||||
move || children(cx)
|
||||
}
|
||||
|
||||
/// Context type that contains information about the current router state.
|
||||
|
|
Loading…
Reference in a new issue