mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-12 23:57:09 +00:00
set up routing
This commit is contained in:
parent
a3c3478831
commit
c1f4616a31
6 changed files with 196 additions and 0 deletions
|
@ -18,6 +18,7 @@ members = [
|
||||||
"leptos_reactive",
|
"leptos_reactive",
|
||||||
"leptos_server",
|
"leptos_server",
|
||||||
"reactive_graph",
|
"reactive_graph",
|
||||||
|
"routing",
|
||||||
"server_fn",
|
"server_fn",
|
||||||
"server_fn_macro",
|
"server_fn_macro",
|
||||||
"server_fn/server_fn_macro_default",
|
"server_fn/server_fn_macro_default",
|
||||||
|
@ -55,6 +56,7 @@ leptos_meta = { path = "./meta", version = "0.6.5" }
|
||||||
next_tuple = { path = "./next_tuple" }
|
next_tuple = { path = "./next_tuple" }
|
||||||
or_poisoned = { path = "./or_poisoned" }
|
or_poisoned = { path = "./or_poisoned" }
|
||||||
reactive_graph = { path = "./reactive_graph" }
|
reactive_graph = { path = "./reactive_graph" }
|
||||||
|
routing = { path = "./routing" }
|
||||||
server_fn = { path = "./server_fn", version = "0.6.5" }
|
server_fn = { path = "./server_fn", version = "0.6.5" }
|
||||||
server_fn_macro = { path = "./server_fn_macro", version = "0.6.5" }
|
server_fn_macro = { path = "./server_fn_macro", version = "0.6.5" }
|
||||||
server_fn_macro_default = { path = "./server_fn/server_fn_macro_default", version = "0.6" }
|
server_fn_macro_default = { path = "./server_fn/server_fn_macro_default", version = "0.6" }
|
||||||
|
|
46
routing/Cargo.toml
Normal file
46
routing/Cargo.toml
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
[package]
|
||||||
|
name = "router"
|
||||||
|
edition = "2021"
|
||||||
|
version.workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
const_str_slice_concat = { workspace = true }
|
||||||
|
next_tuple = { workspace = true }
|
||||||
|
reactive_graph = { workspace = true, optional = true }
|
||||||
|
#paste = "1"
|
||||||
|
thiserror = "1"
|
||||||
|
#tuplestructops = "0.3"
|
||||||
|
url = "2"
|
||||||
|
js-sys = { version = "0.3" }
|
||||||
|
wasm-bindgen = { version = "0.2" }
|
||||||
|
tracing = { version = "0.1", optional = true }
|
||||||
|
|
||||||
|
[dependencies.web-sys]
|
||||||
|
version = "0.3"
|
||||||
|
features = [
|
||||||
|
# History/Routing
|
||||||
|
"History",
|
||||||
|
"HtmlAnchorElement",
|
||||||
|
"Location",
|
||||||
|
"MouseEvent",
|
||||||
|
"Url",
|
||||||
|
# Form
|
||||||
|
"FormData",
|
||||||
|
"HtmlButtonElement",
|
||||||
|
"HtmlFormElement",
|
||||||
|
"HtmlInputElement",
|
||||||
|
"SubmitEvent",
|
||||||
|
"Url",
|
||||||
|
"UrlSearchParams",
|
||||||
|
# Fetching in Hydrate Mode
|
||||||
|
"Headers",
|
||||||
|
"Request",
|
||||||
|
"RequestInit",
|
||||||
|
"RequestMode",
|
||||||
|
"Response",
|
||||||
|
"Window",
|
||||||
|
]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
tracing = ["dep:tracing"]
|
||||||
|
reactive_graph = ["dep:reactive_graph"]
|
12
routing/src/lib.rs
Normal file
12
routing/src/lib.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
//mod generate_route_list;
|
||||||
|
pub mod location;
|
||||||
|
pub mod params;
|
||||||
|
//pub mod matching;
|
||||||
|
//cfg(feature = "reaccy")]
|
||||||
|
//pub mod reactive;
|
||||||
|
//mod render_mode;
|
||||||
|
//pub mod route;
|
||||||
|
//pub mod router;
|
||||||
|
//mod static_render;
|
||||||
|
//pub use generate_route_list::*;
|
||||||
|
//pub use render_mode::*;
|
78
routing/src/location/mod.rs
Normal file
78
routing/src/location/mod.rs
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
use crate::params::Params;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use wasm_bindgen::JsValue;
|
||||||
|
|
||||||
|
mod server;
|
||||||
|
pub use server::*;
|
||||||
|
|
||||||
|
pub(crate) const BASE: &str = "https://leptos.dev";
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||||
|
pub struct Url {
|
||||||
|
pub origin: String,
|
||||||
|
pub pathname: String,
|
||||||
|
pub search: String,
|
||||||
|
pub search_params: Params<String>,
|
||||||
|
pub hash: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A description of a navigation.
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct LocationChange {
|
||||||
|
/// The new URL.
|
||||||
|
pub value: String,
|
||||||
|
/// If true, the new location will replace the current one in the history stack, i.e.,
|
||||||
|
/// clicking the "back" button will not return to the current location.
|
||||||
|
pub replace: bool,
|
||||||
|
/// If true, the router will scroll to the top of the page at the end of the navigation.
|
||||||
|
pub scroll: bool,
|
||||||
|
/// The [`state`](https://developer.mozilla.org/en-US/docs/Web/API/History/state) that will be added during navigation.
|
||||||
|
pub state: State,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for LocationChange {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
value: Default::default(),
|
||||||
|
replace: true,
|
||||||
|
scroll: true,
|
||||||
|
state: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Location {
|
||||||
|
type Error: Debug;
|
||||||
|
|
||||||
|
/// Sets up any global event listeners or other initialization needed.
|
||||||
|
fn init(&self);
|
||||||
|
|
||||||
|
/// Returns the current URL.
|
||||||
|
fn try_to_url(&self) -> Result<Url, Self::Error>;
|
||||||
|
|
||||||
|
fn set_navigation_hook(&mut self, cb: impl Fn(Url) + 'static);
|
||||||
|
|
||||||
|
/// Navigate to a new location.
|
||||||
|
fn navigate(&self, loc: &LocationChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq)]
|
||||||
|
pub struct State(pub Option<JsValue>);
|
||||||
|
|
||||||
|
impl State {
|
||||||
|
pub fn to_js_value(&self) -> JsValue {
|
||||||
|
match &self.0 {
|
||||||
|
Some(v) => v.clone(),
|
||||||
|
None => JsValue::UNDEFINED,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<T> for State
|
||||||
|
where
|
||||||
|
T: Into<JsValue>,
|
||||||
|
{
|
||||||
|
fn from(value: T) -> Self {
|
||||||
|
State(Some(value.into()))
|
||||||
|
}
|
||||||
|
}
|
57
routing/src/location/server.rs
Normal file
57
routing/src/location/server.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
use super::{Location, LocationChange, Url};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct RequestUrl(String);
|
||||||
|
|
||||||
|
impl RequestUrl {
|
||||||
|
/// Creates a server-side request URL from a path, with an optional initial slash.
|
||||||
|
pub fn from_path(path: impl AsRef<str>) -> Self {
|
||||||
|
let path = path.as_ref().trim_start_matches('/');
|
||||||
|
let mut string = String::with_capacity(path.len());
|
||||||
|
string.push_str(path);
|
||||||
|
Self(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for RequestUrl {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(String::from("/"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Location for RequestUrl {
|
||||||
|
type Error = url::ParseError;
|
||||||
|
|
||||||
|
fn init(&self) {}
|
||||||
|
|
||||||
|
fn try_to_url_with_base(&self, base: &str) -> Result<Url, Self::Error> {
|
||||||
|
let url = String::with_capacity(self.0.len() + 1 + base);
|
||||||
|
let url = url::Url::parse(&self.0)?;
|
||||||
|
let search_params = url
|
||||||
|
.query_pairs()
|
||||||
|
.map(|(k, v)| (k.to_string(), v.to_string()))
|
||||||
|
.collect();
|
||||||
|
Ok(Url {
|
||||||
|
origin: url.origin().unicode_serialization(),
|
||||||
|
pathname: url.path().to_string(),
|
||||||
|
search: url.query().unwrap_or_default().to_string(),
|
||||||
|
search_params,
|
||||||
|
hash: Default::default(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_navigation_hook(&mut self, _cb: impl FnMut(Url) + 'static) {}
|
||||||
|
|
||||||
|
fn navigate(&self, _loc: &LocationChange) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::RequestUrl;
|
||||||
|
use crate::location::Location;
|
||||||
|
|
||||||
|
pub fn should_parse_url_without_origin() {
|
||||||
|
let req = RequestUrl::from_path("/foo/bar");
|
||||||
|
let url = req.try_to_url().expect("could not parse URL");
|
||||||
|
}
|
||||||
|
}
|
1
routing/src/params.rs
Normal file
1
routing/src/params.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub(crate) type Params<K> = Vec<(K, String)>;
|
Loading…
Reference in a new issue