feat: more API updates
This commit is contained in:
1 parent
b3ac2ee3f7
commit
a4f280d163
17 files changed
+227
-189
No files matched your search
+51
-67
@@ -1,72 +1,56 @@
|
||||
//! Dioxus-Router
|
||||
//!
|
||||
//! A simple match-based router and router service for most routing needs.
|
||||
//!
|
||||
//! Dioxus-Router is not a *declarative* router. Instead it uses a simple parse-match
|
||||
//! pattern which can be derived via a macro.
|
||||
//!
|
||||
//! ```rust
|
||||
//! fn app(cx: Scope) -> Element {
|
||||
//! let route = use_router(&cx, |svc, path| {
|
||||
//! match path {
|
||||
//! "/about" => Route::About,
|
||||
//! _ => Route::Home,
|
||||
//! }
|
||||
//! });
|
||||
//!
|
||||
//! match route {
|
||||
//! Route::Home => rsx!(cx, h1 { "Home" }),
|
||||
//! Route::About => rsx!(cx, h1 { "About" }),
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
|
||||
mod link;
|
||||
mod platform;
|
||||
mod service;
|
||||
mod userouter;
|
||||
mod utils;
|
||||
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
pub use link::*;
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
pub use service::*;
|
||||
pub use userouter::*;
|
||||
|
||||
use dioxus::Attribute;
|
||||
use dioxus_core as dioxus;
|
||||
|
||||
use dioxus_core::prelude::*;
|
||||
use dioxus_core_macro::{format_args_f, rsx, Props};
|
||||
use dioxus_html as dioxus_elements;
|
||||
// use wasm_bindgen::{JsCast, JsValue};
|
||||
|
||||
use crate::utils::strip_slash_suffix;
|
||||
|
||||
/// Initialize the app's router service and provide access to `Link` components
|
||||
pub fn use_router<R: 'static>(cx: &ScopeState, f: impl Fn(&str) -> R) -> &R {
|
||||
let r = f("/");
|
||||
cx.use_hook(
|
||||
|_| {
|
||||
//
|
||||
r
|
||||
},
|
||||
|f| f,
|
||||
)
|
||||
pub trait Routable:
|
||||
'static + Send + Clone + PartialEq + Serialize + DeserializeOwned + Default
|
||||
{
|
||||
}
|
||||
|
||||
pub trait Routable: 'static + Send + Clone + PartialEq {}
|
||||
impl<T> Routable for T where T: 'static + Send + Clone + PartialEq {}
|
||||
|
||||
#[derive(Props)]
|
||||
pub struct LinkProps<'a, R: Routable> {
|
||||
to: R,
|
||||
|
||||
/// The url that gets pushed to the history stack
|
||||
///
|
||||
/// You can either put it your own inline method or just autoderive the route using `derive(Routable)`
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// Link { to: Route::Home, href: |_| "home".to_string() }
|
||||
///
|
||||
/// // or
|
||||
///
|
||||
/// Link { to: Route::Home, href: Route::as_url }
|
||||
///
|
||||
/// ```
|
||||
#[props(default, setter(strip_option))]
|
||||
href: Option<&'a str>,
|
||||
|
||||
#[props(default, setter(strip_option))]
|
||||
class: Option<&'a str>,
|
||||
|
||||
children: Element<'a>,
|
||||
|
||||
#[props(default)]
|
||||
attributes: Option<&'a [Attribute<'a>]>,
|
||||
}
|
||||
|
||||
pub fn Link<'a, R: Routable>(cx: Scope<'a, LinkProps<'a, R>>) -> Element {
|
||||
// let service = todo!();
|
||||
// let service: todo!() = use_router_service::<R>(&cx)?;
|
||||
let class = cx.props.class.unwrap_or("");
|
||||
cx.render(rsx! {
|
||||
a {
|
||||
href: "#",
|
||||
class: "{class}",
|
||||
{&cx.props.children}
|
||||
// onclick: move |_| service.push_route(cx.props.to.clone()),
|
||||
// href: format_args!("{}", (cx.props.href)(&cx.props.to)),
|
||||
}
|
||||
})
|
||||
impl<T> Routable for T where
|
||||
T: 'static + Send + Clone + PartialEq + Serialize + DeserializeOwned + Default
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
use crate::{Routable, RouterService};
|
||||
use dioxus::Attribute;
|
||||
use dioxus_core as dioxus;
|
||||
use dioxus_core::prelude::*;
|
||||
use dioxus_core_macro::{format_args_f, rsx, Props};
|
||||
use dioxus_html as dioxus_elements;
|
||||
|
||||
#[derive(Props)]
|
||||
pub struct LinkProps<'a, R: Routable> {
|
||||
to: R,
|
||||
|
||||
/// The url that gets pushed to the history stack
|
||||
///
|
||||
/// You can either put it your own inline method or just autoderive the route using `derive(Routable)`
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// Link { to: Route::Home, href: |_| "home".to_string() }
|
||||
///
|
||||
/// // or
|
||||
///
|
||||
/// Link { to: Route::Home, href: Route::as_url }
|
||||
///
|
||||
/// ```
|
||||
#[props(default, setter(strip_option))]
|
||||
href: Option<&'a str>,
|
||||
|
||||
#[props(default, setter(strip_option))]
|
||||
class: Option<&'a str>,
|
||||
|
||||
children: Element<'a>,
|
||||
|
||||
#[props(default)]
|
||||
attributes: Option<&'a [Attribute<'a>]>,
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Link<'a, R: Routable>(cx: Scope<'a, LinkProps<'a, R>>) -> Element {
|
||||
let service = cx.consume_context::<RouterService<R>>()?;
|
||||
cx.render(rsx! {
|
||||
a {
|
||||
href: "#",
|
||||
class: format_args!("{}", cx.props.class.unwrap_or("")),
|
||||
{&cx.props.children}
|
||||
onclick: move |_| service.push_route(cx.props.to.clone()),
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -1 +1,7 @@
|
||||
pub fn parse_current_route() -> String {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub(crate) fn get_base_route() -> String {
|
||||
todo!()
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
use crate::Routable;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
pub struct RouterService<R: Routable> {
|
||||
pub(crate) regen_route: Rc<dyn Fn()>,
|
||||
pub(crate) pending_routes: RefCell<Vec<R>>,
|
||||
}
|
||||
|
||||
impl<R: Routable> RouterService<R> {
|
||||
pub fn current_path(&self) -> &str {
|
||||
todo!()
|
||||
}
|
||||
pub fn push_route(&self, route: R) {
|
||||
self.pending_routes.borrow_mut().push(route);
|
||||
(self.regen_route)();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RouterCfg {
|
||||
initial_route: String,
|
||||
}
|
||||
|
||||
impl RouterCfg {
|
||||
pub fn new(initial_route: String) -> Self {
|
||||
Self { initial_route }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use crate::{Routable, RouterCfg, RouterService};
|
||||
use dioxus_core::ScopeState;
|
||||
|
||||
/// Initialize the app's router service and provide access to `Link` components
|
||||
pub fn use_router<'a, R: Routable>(cx: &'a ScopeState, cfg: impl FnOnce(&mut RouterCfg)) -> &'a R {
|
||||
cx.use_hook(
|
||||
|_| {
|
||||
let svc: RouterService<R> = RouterService {
|
||||
regen_route: cx.schedule_update(),
|
||||
pending_routes: RefCell::new(Vec::new()),
|
||||
};
|
||||
let first_path = R::default();
|
||||
cx.provide_context(svc);
|
||||
UseRouterInner {
|
||||
svc: cx.consume_context::<RouterService<R>>().unwrap(),
|
||||
history: vec![first_path],
|
||||
}
|
||||
},
|
||||
|f| {
|
||||
let mut pending_routes = f.svc.pending_routes.borrow_mut();
|
||||
|
||||
for route in pending_routes.drain(..) {
|
||||
f.history.push(route);
|
||||
}
|
||||
|
||||
f.history.last().unwrap()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
struct UseRouterInner<R: Routable> {
|
||||
svc: Rc<RouterService<R>>,
|
||||
history: Vec<R>,
|
||||
}
|
||||
Reference in new issue
Block a user