mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-10 06:34:20 +00:00
re export renderers in dioxus
This commit is contained in:
parent
b291a5c0b0
commit
af1749d7be
61 changed files with 860 additions and 100 deletions
32
Cargo.lock
generated
32
Cargo.lock
generated
|
@ -2347,13 +2347,19 @@ name = "dioxus"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"criterion 0.3.6",
|
"criterion 0.3.6",
|
||||||
|
"dioxus-config-macro",
|
||||||
"dioxus-core",
|
"dioxus-core",
|
||||||
"dioxus-core-macro",
|
"dioxus-core-macro",
|
||||||
|
"dioxus-desktop",
|
||||||
|
"dioxus-fullstack",
|
||||||
"dioxus-hooks",
|
"dioxus-hooks",
|
||||||
"dioxus-hot-reload",
|
"dioxus-hot-reload",
|
||||||
"dioxus-html",
|
"dioxus-html",
|
||||||
|
"dioxus-liveview",
|
||||||
|
"dioxus-router",
|
||||||
"dioxus-rsx",
|
"dioxus-rsx",
|
||||||
"dioxus-signals",
|
"dioxus-signals",
|
||||||
|
"dioxus-web",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
|
@ -2463,6 +2469,14 @@ dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dioxus-config-macro"
|
||||||
|
version = "0.4.3"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dioxus-core"
|
name = "dioxus-core"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
|
@ -2513,7 +2527,6 @@ dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"dioxus",
|
|
||||||
"dioxus-cli-config",
|
"dioxus-cli-config",
|
||||||
"dioxus-core",
|
"dioxus-core",
|
||||||
"dioxus-core-macro",
|
"dioxus-core-macro",
|
||||||
|
@ -2594,7 +2607,7 @@ dependencies = [
|
||||||
"base64 0.21.7",
|
"base64 0.21.7",
|
||||||
"bytes",
|
"bytes",
|
||||||
"ciborium",
|
"ciborium",
|
||||||
"dioxus",
|
"dioxus-core",
|
||||||
"dioxus-desktop",
|
"dioxus-desktop",
|
||||||
"dioxus-hot-reload",
|
"dioxus-hot-reload",
|
||||||
"dioxus-router",
|
"dioxus-router",
|
||||||
|
@ -2703,13 +2716,25 @@ dependencies = [
|
||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dioxus-lib"
|
||||||
|
version = "0.4.3"
|
||||||
|
dependencies = [
|
||||||
|
"dioxus-config-macro",
|
||||||
|
"dioxus-core",
|
||||||
|
"dioxus-core-macro",
|
||||||
|
"dioxus-hooks",
|
||||||
|
"dioxus-html",
|
||||||
|
"dioxus-rsx",
|
||||||
|
"dioxus-signals",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dioxus-liveview"
|
name = "dioxus-liveview"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum 0.6.20",
|
"axum 0.6.20",
|
||||||
"dioxus",
|
|
||||||
"dioxus-core",
|
"dioxus-core",
|
||||||
"dioxus-hot-reload",
|
"dioxus-hot-reload",
|
||||||
"dioxus-html",
|
"dioxus-html",
|
||||||
|
@ -2806,6 +2831,7 @@ dependencies = [
|
||||||
"dioxus",
|
"dioxus",
|
||||||
"dioxus-cli-config",
|
"dioxus-cli-config",
|
||||||
"dioxus-desktop",
|
"dioxus-desktop",
|
||||||
|
"dioxus-lib",
|
||||||
"dioxus-liveview",
|
"dioxus-liveview",
|
||||||
"dioxus-router",
|
"dioxus-router",
|
||||||
"dioxus-router-macro",
|
"dioxus-router-macro",
|
||||||
|
|
|
@ -2,10 +2,12 @@
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = [
|
members = [
|
||||||
"packages/dioxus",
|
"packages/dioxus",
|
||||||
|
"packages/dioxus-lib",
|
||||||
"packages/core",
|
"packages/core",
|
||||||
"packages/cli",
|
"packages/cli",
|
||||||
"packages/cli-config",
|
"packages/cli-config",
|
||||||
"packages/core-macro",
|
"packages/core-macro",
|
||||||
|
"packages/config-macro",
|
||||||
"packages/router-macro",
|
"packages/router-macro",
|
||||||
"packages/extension",
|
"packages/extension",
|
||||||
"packages/router",
|
"packages/router",
|
||||||
|
@ -57,8 +59,10 @@ version = "0.4.3"
|
||||||
# dependencies that are shared across packages
|
# dependencies that are shared across packages
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
dioxus = { path = "packages/dioxus", version = "0.4.0" }
|
dioxus = { path = "packages/dioxus", version = "0.4.0" }
|
||||||
|
dioxus-lib = { path = "packages/dioxus-lib", version = "0.4.0" }
|
||||||
dioxus-core = { path = "packages/core", version = "0.4.2" }
|
dioxus-core = { path = "packages/core", version = "0.4.2" }
|
||||||
dioxus-core-macro = { path = "packages/core-macro", version = "0.4.0" }
|
dioxus-core-macro = { path = "packages/core-macro", version = "0.4.0" }
|
||||||
|
dioxus-config-macro = { path = "packages/config-macro", version = "0.4.0" }
|
||||||
dioxus-router = { path = "packages/router", version = "0.4.1" }
|
dioxus-router = { path = "packages/router", version = "0.4.1" }
|
||||||
dioxus-router-macro = { path = "packages/router-macro", version = "0.4.1" }
|
dioxus-router-macro = { path = "packages/router-macro", version = "0.4.1" }
|
||||||
dioxus-html = { path = "packages/html", default-features = false, version = "0.4.0" }
|
dioxus-html = { path = "packages/html", default-features = false, version = "0.4.0" }
|
||||||
|
|
26
packages/config-macro/Cargo.toml
Normal file
26
packages/config-macro/Cargo.toml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
[package]
|
||||||
|
name = "dioxus-config-macro"
|
||||||
|
version = { workspace = true }
|
||||||
|
authors = ["Jonathan Kelley"]
|
||||||
|
edition = "2021"
|
||||||
|
description = "Configuration macros for Dioxus"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
repository = "https://github.com/DioxusLabs/dioxus/"
|
||||||
|
homepage = "https://dioxuslabs.com"
|
||||||
|
keywords = ["dom", "ui", "gui", "react"]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
proc-macro2 = { version = "1.0" }
|
||||||
|
quote = "1.0"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
fullstack = []
|
||||||
|
desktop = []
|
||||||
|
web = []
|
||||||
|
ssr = []
|
||||||
|
liveview = []
|
||||||
|
tui = []
|
39
packages/config-macro/README.md
Normal file
39
packages/config-macro/README.md
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# dioxus-config-macro
|
||||||
|
|
||||||
|
[![Crates.io][crates-badge]][crates-url]
|
||||||
|
[![MIT licensed][mit-badge]][mit-url]
|
||||||
|
[![Build Status][actions-badge]][actions-url]
|
||||||
|
[![Discord chat][discord-badge]][discord-url]
|
||||||
|
|
||||||
|
[crates-badge]: https://img.shields.io/crates/v/dioxus-config-macro.svg
|
||||||
|
[crates-url]: https://crates.io/crates/dioxus-config-macro
|
||||||
|
[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg
|
||||||
|
[mit-url]: https://github.com/dioxuslabs/dioxus/blob/master/LICENSE
|
||||||
|
[actions-badge]: https://github.com/dioxuslabs/dioxus/actions/workflows/main.yml/badge.svg
|
||||||
|
[actions-url]: https://github.com/dioxuslabs/dioxus/actions?query=workflow%3ACI+branch%3Amaster
|
||||||
|
[discord-badge]: https://img.shields.io/discord/899851952891002890.svg?logo=discord&style=flat-square
|
||||||
|
[discord-url]: https://discord.gg/XgGxMSkvUM
|
||||||
|
|
||||||
|
[Website](https://dioxuslabs.com) |
|
||||||
|
[Guides](https://dioxuslabs.com/learn/0.4/) |
|
||||||
|
[API Docs](https://docs.rs/dioxus-config-macro/latest/dioxus_core_macro) |
|
||||||
|
[Chat](https://discord.gg/XgGxMSkvUM)
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
`dioxus-config-macro` provides a handful of helpful macros to make it easier to work with optional sections of the launch builder.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
- Report issues on our [issue tracker](https://github.com/dioxuslabs/dioxus/issues).
|
||||||
|
- Join the discord and ask questions!
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the [MIT license].
|
||||||
|
|
||||||
|
[mit license]: https://github.com/DioxusLabs/dioxus/blob/master/LICENSE-MIT
|
||||||
|
|
||||||
|
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||||
|
for inclusion in Dioxus by you shall be licensed as MIT without any additional
|
||||||
|
terms or conditions.
|
112
packages/config-macro/src/lib.rs
Normal file
112
packages/config-macro/src/lib.rs
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
#![doc = include_str!("../README.md")]
|
||||||
|
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")]
|
||||||
|
#![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")]
|
||||||
|
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use proc_macro2::TokenStream as TokenStream2;
|
||||||
|
use quote::quote;
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn server(input: TokenStream) -> TokenStream {
|
||||||
|
if cfg!(any(feature = "ssr", feature = "liveview")) {
|
||||||
|
let input = TokenStream2::from(input);
|
||||||
|
quote! {
|
||||||
|
Some(#input)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn client(input: TokenStream) -> TokenStream {
|
||||||
|
if cfg!(any(feature = "desktop", feature = "web", feature = "tui")) {
|
||||||
|
let input = TokenStream2::from(input);
|
||||||
|
quote! {
|
||||||
|
Some(#input)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn desktop(input: TokenStream) -> TokenStream {
|
||||||
|
if cfg!(feature = "desktop") {
|
||||||
|
let input = TokenStream2::from(input);
|
||||||
|
quote! {
|
||||||
|
Some(#input)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn fullstack(input: TokenStream) -> TokenStream {
|
||||||
|
if cfg!(feature = "web") {
|
||||||
|
let input = TokenStream2::from(input);
|
||||||
|
quote! {
|
||||||
|
Some(#input)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn ssr(input: TokenStream) -> TokenStream {
|
||||||
|
if cfg!(feature = "ssr") {
|
||||||
|
let input = TokenStream2::from(input);
|
||||||
|
quote! {
|
||||||
|
Some(#input)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn liveview(input: TokenStream) -> TokenStream {
|
||||||
|
if cfg!(feature = "liveview") {
|
||||||
|
let input = TokenStream2::from(input);
|
||||||
|
quote! {
|
||||||
|
Some(#input)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn tui(input: TokenStream) -> TokenStream {
|
||||||
|
if cfg!(feature = "tui") {
|
||||||
|
let input = TokenStream2::from(input);
|
||||||
|
quote! {
|
||||||
|
Some(#input)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
|
@ -185,7 +185,7 @@ impl Parse for ComponentBody {
|
||||||
fn parse(input: ParseStream) -> Result<Self> {
|
fn parse(input: ParseStream) -> Result<Self> {
|
||||||
let item_fn: ItemFn = input.parse()?;
|
let item_fn: ItemFn = input.parse()?;
|
||||||
|
|
||||||
let element_type_path = "::dioxus::core::Element";
|
let element_type_path = "dioxus_core::Element";
|
||||||
|
|
||||||
if item_fn.sig.output == ReturnType::Default {
|
if item_fn.sig.output == ReturnType::Default {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
|
|
|
@ -691,7 +691,7 @@ Finally, call `.build()` to create the instance of `{name}`.
|
||||||
_phantom: (#( #phantom_generics ),*),
|
_phantom: (#( #phantom_generics ),*),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #impl_generics ::dioxus::prelude::Properties for #name #ty_generics
|
impl #impl_generics dioxus_core::prelude::Properties for #name #ty_generics
|
||||||
#b_generics_where_extras_predicates
|
#b_generics_where_extras_predicates
|
||||||
{
|
{
|
||||||
type Builder = #builder_name #generics_with_empty;
|
type Builder = #builder_name #generics_with_empty;
|
||||||
|
@ -826,20 +826,20 @@ Finally, call `.build()` to create the instance of `{name}`.
|
||||||
|
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
#[allow(dead_code, non_camel_case_types, missing_docs)]
|
#[allow(dead_code, non_camel_case_types, missing_docs)]
|
||||||
impl #impl_generics ::dioxus::prelude::HasAttributes for #builder_name < #( #ty_generics ),* > #where_clause {
|
impl #impl_generics dioxus_core::prelude::HasAttributes for #builder_name < #( #ty_generics ),* > #where_clause {
|
||||||
fn push_attribute(
|
fn push_attribute(
|
||||||
mut self,
|
mut self,
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
ns: Option<&'static str>,
|
ns: Option<&'static str>,
|
||||||
attr: impl ::dioxus::prelude::IntoAttributeValue,
|
attr: impl dioxus_core::prelude::IntoAttributeValue,
|
||||||
volatile: bool
|
volatile: bool
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let ( #(#descructuring,)* ) = self.fields;
|
let ( #(#descructuring,)* ) = self.fields;
|
||||||
self.#field_name.push(
|
self.#field_name.push(
|
||||||
::dioxus::core::Attribute::new(
|
dioxus_core::Attribute::new(
|
||||||
name,
|
name,
|
||||||
{
|
{
|
||||||
use ::dioxus::prelude::IntoAttributeValue;
|
use dioxus_core::prelude::IntoAttributeValue;
|
||||||
attr.into_value()
|
attr.into_value()
|
||||||
},
|
},
|
||||||
ns,
|
ns,
|
||||||
|
|
|
@ -34,7 +34,7 @@ The `dioxus` crate exports the `rsx` macro which transforms a helpful, simpler s
|
||||||
First, start with your app:
|
First, start with your app:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
# use dioxus::core::Mutations;
|
# use dioxus::dioxus_core::Mutations;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
// First, declare a root component
|
// First, declare a root component
|
||||||
|
|
|
@ -73,10 +73,11 @@ pub(crate) mod innerlude {
|
||||||
|
|
||||||
pub use crate::innerlude::{
|
pub use crate::innerlude::{
|
||||||
fc_to_builder, generation, schedule_update, schedule_update_any, use_hook, vdom_is_rendering,
|
fc_to_builder, generation, schedule_update, schedule_update_any, use_hook, vdom_is_rendering,
|
||||||
AnyValue, Attribute, AttributeValue, CapturedError, Component, DynamicNode, Element, ElementId,
|
AnyValue, Attribute, AttributeValue, CapturedError, Component, ComponentFunction, DynamicNode,
|
||||||
Event, Fragment, HasAttributes, IntoDynNode, Mutation, Mutations, NoOpMutations, Properties,
|
Element, ElementId, Event, Fragment, HasAttributes, IntoDynNode, Mutation, Mutations,
|
||||||
RenderReturn, ScopeId, ScopeState, Task, Template, TemplateAttribute, TemplateNode, VComponent,
|
NoOpMutations, Properties, RenderReturn, ScopeId, ScopeState, Task, Template,
|
||||||
VNode, VNodeInner, VPlaceholder, VText, VirtualDom, WriteMutations,
|
TemplateAttribute, TemplateNode, VComponent, VNode, VNodeInner, VPlaceholder, VText,
|
||||||
|
VirtualDom, WriteMutations,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The purpose of this module is to alleviate imports of many common types
|
/// The purpose of this module is to alleviate imports of many common types
|
||||||
|
|
|
@ -113,8 +113,10 @@ where
|
||||||
///
|
///
|
||||||
/// > Note: If you get an error about the `ComponentFunction` trait not being implemented: make sure your props implements the `Properties` trait or if you would like to declare your props inline, make sure you use the #[component] macro on your function.
|
/// > Note: If you get an error about the `ComponentFunction` trait not being implemented: make sure your props implements the `Properties` trait or if you would like to declare your props inline, make sure you use the #[component] macro on your function.
|
||||||
pub trait ComponentFunction<P> {
|
pub trait ComponentFunction<P> {
|
||||||
|
/// The props type for this component.
|
||||||
type Props: 'static;
|
type Props: 'static;
|
||||||
|
|
||||||
|
/// Run the component function with the given props.
|
||||||
fn call(&self, props: Self::Props) -> Element;
|
fn call(&self, props: Self::Props) -> Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,23 @@ impl ScopeContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Inject a Box<dyn Any> into the context of this scope
|
||||||
|
pub(crate) fn provide_any_context(&self, mut value: Box<dyn Any>) {
|
||||||
|
let mut contexts = self.shared_contexts.borrow_mut();
|
||||||
|
|
||||||
|
// If the context exists, swap it out for the new value
|
||||||
|
for ctx in contexts.iter_mut() {
|
||||||
|
// Swap the ptr directly
|
||||||
|
if ctx.as_ref().type_id() == value.as_ref().type_id() {
|
||||||
|
std::mem::swap(ctx, &mut value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Else, just push it
|
||||||
|
contexts.push(value);
|
||||||
|
}
|
||||||
|
|
||||||
/// Expose state to children further down the [`crate::VirtualDom`] Tree. Requires `Clone` on the context to allow getting values down the tree.
|
/// Expose state to children further down the [`crate::VirtualDom`] Tree. Requires `Clone` on the context to allow getting values down the tree.
|
||||||
///
|
///
|
||||||
/// This is a "fundamental" operation and should only be called during initialization of a hook.
|
/// This is a "fundamental" operation and should only be called during initialization of a hook.
|
||||||
|
|
|
@ -325,6 +325,14 @@ impl VirtualDom {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Build the virtualdom with a global context inserted into the base scope
|
||||||
|
///
|
||||||
|
/// This method is useful for when you want to provide a context in your app without knowing its type
|
||||||
|
pub fn with_boxed_root_context(self, context: Box<dyn Any>) -> Self {
|
||||||
|
self.base_scope().context().provide_any_context(context);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Manually mark a scope as requiring a re-render
|
/// Manually mark a scope as requiring a re-render
|
||||||
///
|
///
|
||||||
/// Whenever the Runtime "works", it will re-render this scope
|
/// Whenever the Runtime "works", it will re-render this scope
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! This tests to ensure we clean it up
|
//! This tests to ensure we clean it up
|
||||||
|
|
||||||
use dioxus::core::{ElementId, Mutation::*};
|
use dioxus::dioxus_core::{ElementId, Mutation::*};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use dioxus::core::{ElementId, Mutation::*};
|
use dioxus::dioxus_core::{ElementId, Mutation::*};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use dioxus::core::{ElementId, Mutation::*};
|
use dioxus::dioxus_core::{ElementId, Mutation::*};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
//! This methods all use "rebuild_to_vec" which completely bypasses the scheduler.
|
//! This methods all use "rebuild_to_vec" which completely bypasses the scheduler.
|
||||||
//! Hard rebuild_to_vecs don't consume any events from the event queue.
|
//! Hard rebuild_to_vecs don't consume any events from the event queue.
|
||||||
|
|
||||||
use dioxus::core::Mutation::*;
|
use dioxus::dioxus_core::Mutation::*;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_core::ElementId;
|
use dioxus_core::ElementId;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// use dioxus::core::Mutation::*;
|
// use dioxus::dioxus_core::Mutation::*;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Do we create fragments properly across complex boundaries?
|
//! Do we create fragments properly across complex boundaries?
|
||||||
|
|
||||||
use dioxus::core::Mutation::*;
|
use dioxus::dioxus_core::Mutation::*;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_core::ElementId;
|
use dioxus_core::ElementId;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use dioxus::core::Mutation::*;
|
use dioxus::dioxus_core::Mutation::*;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_core::ElementId;
|
use dioxus_core::ElementId;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use dioxus::core::Mutation::*;
|
use dioxus::dioxus_core::Mutation::*;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_core::ElementId;
|
use dioxus_core::ElementId;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use dioxus::core::{ElementId, Mutation::*};
|
use dioxus::dioxus_core::{ElementId, Mutation::*};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
/// As we clean up old templates, the ID for the node should cycle
|
/// As we clean up old templates, the ID for the node should cycle
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use dioxus::core::{ElementId, Mutation::*};
|
use dioxus::dioxus_core::{ElementId, Mutation::*};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
/// When returning sets of components, we do a light diff of the contents to preserve some react-like functionality
|
/// When returning sets of components, we do a light diff of the contents to preserve some react-like functionality
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use dioxus::core::Mutation::*;
|
use dioxus::dioxus_core::Mutation::*;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_core::{ElementId, NoOpMutations};
|
use dioxus_core::{ElementId, NoOpMutations};
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
//!
|
//!
|
||||||
//! It does not validated that component lifecycles work properly. This is done in another test file.
|
//! It does not validated that component lifecycles work properly. This is done in another test file.
|
||||||
|
|
||||||
use dioxus::core::{ElementId, Mutation::*};
|
use dioxus::dioxus_core::{ElementId, Mutation::*};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
/// Should result in moves, but not removals or additions
|
/// Should result in moves, but not removals or additions
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use dioxus::core::{ElementId, Mutation::*};
|
use dioxus::dioxus_core::{ElementId, Mutation::*};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use dioxus::core::{ElementId, Mutation};
|
use dioxus::dioxus_core::{ElementId, Mutation};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn basic_syntax_is_a_template() -> Element {
|
fn basic_syntax_is_a_template() -> Element {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
//! Tests for the lifecycle of components.
|
//! Tests for the lifecycle of components.
|
||||||
use dioxus::core::{ElementId, Mutation::*};
|
use dioxus::dioxus_core::{ElementId, Mutation::*};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_html::SerializedHtmlEventConverter;
|
use dioxus_html::SerializedHtmlEventConverter;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
|
@ -81,7 +81,6 @@ features = ["tokio_runtime", "hot-reload"]
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
dioxus-core-macro = { workspace = true }
|
dioxus-core-macro = { workspace = true }
|
||||||
dioxus-hooks = { workspace = true }
|
dioxus-hooks = { workspace = true }
|
||||||
dioxus = { workspace = true }
|
|
||||||
exitcode = "1.1.2"
|
exitcode = "1.1.2"
|
||||||
scraper = "0.16.0"
|
scraper = "0.16.0"
|
||||||
|
|
||||||
|
|
27
packages/dioxus-lib/Cargo.toml
Normal file
27
packages/dioxus-lib/Cargo.toml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
[package]
|
||||||
|
name = "dioxus-lib"
|
||||||
|
version = { workspace = true }
|
||||||
|
authors = ["Jonathan Kelley", "Dioxus Labs", "ealmloff"]
|
||||||
|
edition = "2021"
|
||||||
|
description = "Portable, performant, and ergonomic framework for building cross-platform user interfaces in Rust"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
repository = "https://github.com/DioxusLabs/dioxus/"
|
||||||
|
homepage = "https://dioxuslabs.com/learn/0.4/"
|
||||||
|
keywords = ["dom", "ui", "gui", "react", "wasm"]
|
||||||
|
rust-version = "1.65.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
dioxus-core = { workspace = true }
|
||||||
|
dioxus-html = { workspace = true, optional = true }
|
||||||
|
dioxus-core-macro = { workspace = true, optional = true }
|
||||||
|
dioxus-config-macro = { workspace = true, optional = true }
|
||||||
|
dioxus-hooks = { workspace = true, optional = true }
|
||||||
|
dioxus-rsx = { workspace = true, optional = true }
|
||||||
|
dioxus-signals = { workspace = true, optional = true }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["macro", "html", "signals"]
|
||||||
|
signals = ["dioxus-signals"]
|
||||||
|
macro = ["dioxus-core-macro", "dioxus-rsx"]
|
||||||
|
html = ["dioxus-html"]
|
||||||
|
hooks = ["dioxus-hooks"]
|
341
packages/dioxus-lib/README.md
Normal file
341
packages/dioxus-lib/README.md
Normal file
|
@ -0,0 +1,341 @@
|
||||||
|
<div style="text-align: center">
|
||||||
|
<h1>🌗🚀 Dioxus</h1>
|
||||||
|
<p>
|
||||||
|
<strong>A concurrent, functional, virtual DOM for Rust</strong>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
# Resources
|
||||||
|
|
||||||
|
This overview provides a brief introduction to Dioxus. For a more in-depth guide, make sure to check out:
|
||||||
|
|
||||||
|
- [Getting Started](https://dioxuslabs.com/learn/0.4/getting_started)
|
||||||
|
- [Book (0.4)](https://dioxuslabs.com/learn/0.4/)
|
||||||
|
- [Examples](https://github.com/DioxusLabs/example-projects)
|
||||||
|
|
||||||
|
# Overview and Goals
|
||||||
|
|
||||||
|
Dioxus makes it easy to quickly build complex user interfaces with Rust. Any Dioxus app can run in the web browser,
|
||||||
|
as a desktop app, as a mobile app, or anywhere else provided you build the right renderer.
|
||||||
|
|
||||||
|
Dioxus is heavily inspired by React, supporting many of the same concepts:
|
||||||
|
|
||||||
|
- Hooks for state
|
||||||
|
- VirtualDom & diffing
|
||||||
|
- Concurrency, fibers, and asynchronous rendering
|
||||||
|
- JSX-like templating syntax
|
||||||
|
|
||||||
|
If you know React, then you know Dioxus.
|
||||||
|
|
||||||
|
Dioxus is _substantially_ more performant than many of the other Rust UI libraries (Yew/Percy) and is _significantly_ more performant
|
||||||
|
than React—roughly competitive with InfernoJS.
|
||||||
|
|
||||||
|
Remember: Dioxus is a library for declaring interactive user interfaces—it is not a dedicated renderer. Most 1st party renderers for Dioxus currently only support web technologies.
|
||||||
|
|
||||||
|
## Brief Overview
|
||||||
|
|
||||||
|
All Dioxus apps are built by composing functions that take in a `Scope` which is generic over some `Properties` and return an `Element`.
|
||||||
|
A `Scope` holds relevant state data for the currently rendered component.
|
||||||
|
|
||||||
|
To launch an app, we use the `launch` method for the specific renderer we want to use. In the launch function, we pass the app's `Component`.
|
||||||
|
|
||||||
|
```rust, ignore
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
dioxus_desktop::launch(App);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The #[component] attribute streamlines component creation.
|
||||||
|
// It's not required, but highly recommended. For example, UpperCamelCase components will not generate a warning.
|
||||||
|
#[component]
|
||||||
|
fn App() -> Element {
|
||||||
|
rsx!("hello world!"))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Elements & your first component
|
||||||
|
|
||||||
|
To assemble UI trees with Dioxus, you need to use the `render` function on
|
||||||
|
something called `LazyNodes`. To produce `LazyNodes`, you can use the `rsx!`
|
||||||
|
macro or the NodeFactory API. For the most part, you want to use the `rsx!`
|
||||||
|
macro.
|
||||||
|
|
||||||
|
Any element in `rsx!` can have attributes, listeners, and children. For
|
||||||
|
consistency, we force all attributes and listeners to be listed _before_
|
||||||
|
children.
|
||||||
|
|
||||||
|
```rust, ignore
|
||||||
|
let value = "123";
|
||||||
|
|
||||||
|
rsx!(
|
||||||
|
div {
|
||||||
|
class: "my-class {value}", // <--- attribute
|
||||||
|
onclick: move |_| log::info!("clicked!"), // <--- listener
|
||||||
|
h1 { "hello world" }, // <--- child
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
The `rsx!` macro accepts attributes in "struct form" and will parse the rest
|
||||||
|
of the body as child elements and rust expressions. Any rust expression that
|
||||||
|
implements `IntoIterator<Item = impl IntoVNode>` will be parsed as a child.
|
||||||
|
|
||||||
|
```rust, ignore
|
||||||
|
rsx!(
|
||||||
|
div {
|
||||||
|
(0..10).map(|_| rsx!(span { "hello world" }))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Used within components, the `rsx!` macro must be rendered into an `Element` with
|
||||||
|
the `render` function on Scope.
|
||||||
|
|
||||||
|
If we want to omit the boilerplate of `cx.render`, we can simply pass in
|
||||||
|
`cx` as the first argument of rsx. This is sometimes useful when we need to
|
||||||
|
render nodes in match statements.
|
||||||
|
|
||||||
|
```rust, ignore
|
||||||
|
#[component[
|
||||||
|
fn Example() -> Element {
|
||||||
|
|
||||||
|
// both of these are equivalent
|
||||||
|
rsx!("hello world"))
|
||||||
|
|
||||||
|
render!("hello world!")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Putting everything together, we can write a simple component that renders a list of
|
||||||
|
elements:
|
||||||
|
|
||||||
|
```rust, ignore
|
||||||
|
#[component]
|
||||||
|
fn App() -> Element {
|
||||||
|
let name = "dave";
|
||||||
|
rsx!(
|
||||||
|
h1 { "Hello, {name}!" }
|
||||||
|
div {
|
||||||
|
class: "my-class",
|
||||||
|
id: "my-id",
|
||||||
|
|
||||||
|
(0..5).map(|i| rsx!(
|
||||||
|
div { key: "{i}"
|
||||||
|
"FizzBuzz: {i}"
|
||||||
|
}
|
||||||
|
))
|
||||||
|
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
We can compose these function components to build a complex app. Each new
|
||||||
|
component we design must take some Properties. For components with no explicit
|
||||||
|
properties, we can use the `()` type or simply omit the type altogether.
|
||||||
|
|
||||||
|
In Dioxus, all properties are memoized by default!
|
||||||
|
|
||||||
|
```rust, ignore
|
||||||
|
#[component]
|
||||||
|
fn App() -> Element {
|
||||||
|
rsx!(
|
||||||
|
Header {
|
||||||
|
title: "My App",
|
||||||
|
color: "red",
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Our `Header` component takes a `title` and a `color` property, which we
|
||||||
|
declare on an explicit `HeaderProps` struct.
|
||||||
|
|
||||||
|
```rust, ignore
|
||||||
|
// The `Props` derive macro lets us add additional functionality to how props are interpreted.
|
||||||
|
#[derive(Props, PartialEq)]
|
||||||
|
struct HeaderProps {
|
||||||
|
title: String,
|
||||||
|
color: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
fn Header(cx: Scope<HeaderProps>) -> Element {
|
||||||
|
rsx!(
|
||||||
|
div {
|
||||||
|
background_color: "{cx.props.color}"
|
||||||
|
h1 { "{cx.props.title}" }
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `#[component]` macro also allows you to derive the props
|
||||||
|
struct from function arguments:
|
||||||
|
|
||||||
|
```rust, ignore
|
||||||
|
#[component]
|
||||||
|
fn Header(title: String, color: String) -> Element {
|
||||||
|
rsx!(
|
||||||
|
div {
|
||||||
|
background_color: "{color}"
|
||||||
|
h1 { "{title}" }
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Components may also borrow data from their parent component. We just need to
|
||||||
|
attach some lifetimes to the props struct.
|
||||||
|
|
||||||
|
> Note: we don't need to derive `PartialEq` for borrowed props since they cannot be memoized.
|
||||||
|
|
||||||
|
```rust, ignore
|
||||||
|
#[derive(Props)]
|
||||||
|
struct HeaderProps<'a> {
|
||||||
|
title: &'a str,
|
||||||
|
color: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
fn Header(props: HeaderProps -> Element {
|
||||||
|
rsx!(
|
||||||
|
div {
|
||||||
|
background_color: "{cx.props.color}"
|
||||||
|
h1 { "{cx.props.title}" }
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Components that begin with an uppercase letter may be called with
|
||||||
|
the traditional (for React) curly-brace syntax like so:
|
||||||
|
|
||||||
|
```rust, ignore
|
||||||
|
rsx!(
|
||||||
|
Header { title: "My App" }
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, if your components begin with a lowercase letter, you can use
|
||||||
|
the function call syntax:
|
||||||
|
|
||||||
|
```rust, ignore
|
||||||
|
rsx!(
|
||||||
|
header( title: "My App" )
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
However, the convention is to use UpperCamelCase. The `#[component]` attribute will enforce this,
|
||||||
|
but you can turn it off if you wish.
|
||||||
|
|
||||||
|
## Hooks
|
||||||
|
|
||||||
|
While components are reusable forms of UI elements, hooks are reusable forms
|
||||||
|
of logic. Hooks provide us a way of retrieving state from the `Scope` and using
|
||||||
|
it to render UI elements.
|
||||||
|
|
||||||
|
By convention, all hooks are functions that should start with `use_`. We can
|
||||||
|
use hooks to define the state and modify it from within listeners.
|
||||||
|
|
||||||
|
```rust, ignore
|
||||||
|
#[component]
|
||||||
|
fn App() -> Element {
|
||||||
|
let name = use_signal(|| "world");
|
||||||
|
|
||||||
|
render!("hello {name}!")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Hooks are sensitive to how they are used. To use hooks, you must abide by the
|
||||||
|
["rules of hooks" (borrowed from React)](https://reactjs.org/docs/hooks-rules.html):
|
||||||
|
|
||||||
|
- Functions with "use\_" should not be called in callbacks
|
||||||
|
- Functions with "use\_" should not be called out of order
|
||||||
|
- Functions with "use\_" should not be called in loops or conditionals
|
||||||
|
|
||||||
|
In a sense, hooks let us add a field of state to our component without declaring
|
||||||
|
an explicit state struct. However, this means we need to "load" the struct in the right
|
||||||
|
order. If that order is wrong, then the hook will pick the wrong state and panic.
|
||||||
|
|
||||||
|
Most hooks you'll write are simply compositions of other hooks:
|
||||||
|
|
||||||
|
```rust, ignore
|
||||||
|
fn use_username(d: Uuid) -> bool {
|
||||||
|
let users = use_context::<Users>();
|
||||||
|
users.get(&id).map(|user| user.logged_in).ok_or(false)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
To create entirely new foundational hooks, we can use the `use_hook` method on `ScopeState`.
|
||||||
|
|
||||||
|
```rust, ignore
|
||||||
|
fn use_mut_string() -> &mut String {
|
||||||
|
cx.use_hook(|_| "Hello".to_string())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to extend Dioxus with some new functionality, you'll probably want to implement a new hook from scratch.
|
||||||
|
|
||||||
|
## Putting it all together
|
||||||
|
|
||||||
|
Using components, templates, and hooks, we can build a simple app.
|
||||||
|
|
||||||
|
```rust, ignore
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
dioxus_desktop::launch(App);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
fn App() -> Element {
|
||||||
|
let count = use_signal(|| 0);
|
||||||
|
|
||||||
|
rsx!(
|
||||||
|
div { "Count: {count}" }
|
||||||
|
button { onclick: move |_| count.set(count + 1), "Increment" }
|
||||||
|
button { onclick: move |_| count.set(count - 1), "Decrement" }
|
||||||
|
))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
This overview doesn't cover everything. Make sure to check out the tutorial and reference guide on the official
|
||||||
|
website for more details.
|
||||||
|
|
||||||
|
Beyond this overview, Dioxus supports:
|
||||||
|
|
||||||
|
- Server-side rendering
|
||||||
|
- Concurrent rendering (with async support)
|
||||||
|
- Web/Desktop/Mobile support
|
||||||
|
- Pre-rendering and rehydration
|
||||||
|
- Fragments, Portals, and Suspense
|
||||||
|
- Inline-styles
|
||||||
|
- Custom event handlers
|
||||||
|
- Custom elements
|
||||||
|
- Basic fine-grained reactivity (IE SolidJS/Svelte)
|
||||||
|
- and more!
|
||||||
|
|
||||||
|
Good luck!
|
||||||
|
|
||||||
|
## Inspiration, Resources, Alternatives, and Credits
|
||||||
|
|
||||||
|
Dioxus is inspired by:
|
||||||
|
|
||||||
|
- React: for its hooks, concurrency, suspense
|
||||||
|
- Dodrio: for its research in bump allocation, double buffering, and diffing architecture
|
||||||
|
|
||||||
|
Alternatives to Dioxus include:
|
||||||
|
|
||||||
|
- Yew: supports function components and web, but no SSR, borrowed data, or bump allocation. Rather slow at times.
|
||||||
|
- Percy: supports function components, web, ssr, but lacks state management
|
||||||
|
- Sycamore: supports function components, web, ssr, but is closer to SolidJS than React
|
||||||
|
- MoonZoom/Seed: opinionated frameworks based on the Elm model (message, update)—no hooks
|
||||||
|
|
||||||
|
We've put a lot of work into making Dioxus ergonomic and _familiar_.
|
||||||
|
Our target audience is TypeScript developers looking to switch to Rust for the web—so we need to be comparable to React.
|
48
packages/dioxus-lib/src/lib.rs
Normal file
48
packages/dioxus-lib/src/lib.rs
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
#![doc = include_str!("../README.md")]
|
||||||
|
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")]
|
||||||
|
#![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")]
|
||||||
|
|
||||||
|
#[cfg(feature = "hooks")]
|
||||||
|
pub use dioxus_hooks as hooks;
|
||||||
|
|
||||||
|
#[cfg(feature = "signals")]
|
||||||
|
pub use dioxus_signals as signals;
|
||||||
|
|
||||||
|
pub mod events {
|
||||||
|
#[cfg(feature = "html")]
|
||||||
|
pub use dioxus_html::prelude::*;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "html")]
|
||||||
|
pub use dioxus_html as html;
|
||||||
|
|
||||||
|
#[cfg(feature = "macro")]
|
||||||
|
pub use dioxus_rsx as rsx;
|
||||||
|
|
||||||
|
#[cfg(feature = "macro")]
|
||||||
|
pub use dioxus_core_macro as core_macro;
|
||||||
|
|
||||||
|
pub mod prelude {
|
||||||
|
#[cfg(feature = "hooks")]
|
||||||
|
pub use crate::hooks::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "signals")]
|
||||||
|
pub use dioxus_signals::*;
|
||||||
|
|
||||||
|
pub use dioxus_core::prelude::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "macro")]
|
||||||
|
#[allow(deprecated)]
|
||||||
|
pub use dioxus_core_macro::{component, format_args_f, inline_props, render, rsx, Props};
|
||||||
|
|
||||||
|
#[cfg(feature = "launch")]
|
||||||
|
pub use dioxus_config_macro::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "html")]
|
||||||
|
pub use dioxus_html as dioxus_elements;
|
||||||
|
|
||||||
|
#[cfg(feature = "html")]
|
||||||
|
pub use dioxus_elements::{prelude::*, GlobalAttributes, SvgAttributes};
|
||||||
|
|
||||||
|
pub use dioxus_core;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
use dioxus::core::RenderReturn;
|
use dioxus::dioxus_core::RenderReturn;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_tui::DioxusElementToNodeId;
|
use dioxus_tui::DioxusElementToNodeId;
|
||||||
use dioxus_tui::Query;
|
use dioxus_tui::Query;
|
||||||
|
|
|
@ -14,21 +14,38 @@ rust-version = "1.65.0"
|
||||||
dioxus-core = { workspace = true }
|
dioxus-core = { workspace = true }
|
||||||
dioxus-html = { workspace = true, optional = true }
|
dioxus-html = { workspace = true, optional = true }
|
||||||
dioxus-core-macro = { workspace = true, optional = true }
|
dioxus-core-macro = { workspace = true, optional = true }
|
||||||
|
dioxus-config-macro = { workspace = true, optional = true }
|
||||||
dioxus-hooks = { workspace = true, optional = true }
|
dioxus-hooks = { workspace = true, optional = true }
|
||||||
dioxus-rsx = { workspace = true, optional = true }
|
dioxus-rsx = { workspace = true, optional = true }
|
||||||
dioxus-signals = { workspace = true, optional = true }
|
dioxus-signals = { workspace = true, optional = true }
|
||||||
|
dioxus-router = { workspace = true, optional = true }
|
||||||
|
dioxus-web = { workspace = true, optional = true }
|
||||||
|
dioxus-desktop = { workspace = true, optional = true }
|
||||||
|
dioxus-fullstack = { workspace = true, optional = true }
|
||||||
|
dioxus-liveview = { workspace = true, optional = true }
|
||||||
|
# dioxus-tui = { workspace = true, optional = true }
|
||||||
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
dioxus-hot-reload = { workspace = true, optional = true }
|
dioxus-hot-reload = { workspace = true, optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["macro", "html", "hot-reload", "signals"]
|
default = ["macro", "html", "hot-reload", "signals", "launch"]
|
||||||
signals = ["dioxus-signals"]
|
signals = ["dioxus-signals"]
|
||||||
macro = ["dioxus-core-macro", "dioxus-rsx"]
|
macro = ["dioxus-core-macro", "dioxus-rsx"]
|
||||||
html = ["dioxus-html"]
|
html = ["dioxus-html"]
|
||||||
hooks = ["dioxus-hooks"]
|
hooks = ["dioxus-hooks"]
|
||||||
hot-reload = ["dioxus-hot-reload"]
|
hot-reload = ["dioxus-hot-reload"]
|
||||||
|
|
||||||
|
launch = ["dioxus-config-macro"]
|
||||||
|
router = ["dioxus-router"]
|
||||||
|
|
||||||
|
# Platforms
|
||||||
|
fullstack = ["dioxus-fullstack"]
|
||||||
|
desktop = ["dioxus-desktop", "dioxus-fullstack?/desktop"]
|
||||||
|
web = ["dioxus-web", "dioxus-fullstack?/web"]
|
||||||
|
ssr = ["dioxus-fullstack?/ssr"]
|
||||||
|
liveview = ["dioxus-desktop"]
|
||||||
|
# tui = ["dioxus-tui"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
futures-util = { workspace = true }
|
futures-util = { workspace = true }
|
||||||
|
|
102
packages/dioxus/src/launch.rs
Normal file
102
packages/dioxus/src/launch.rs
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
//! Launch helper macros for fullstack apps
|
||||||
|
#![allow(unused)]
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
|
use crate::prelude::*;
|
||||||
|
use dioxus_core::prelude::*;
|
||||||
|
use dioxus_core::ComponentFunction;
|
||||||
|
|
||||||
|
pub trait ClonableAny: Any {
|
||||||
|
fn clone_box(&self) -> Box<dyn ClonableAny>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Any + Clone> ClonableAny for T {
|
||||||
|
fn clone_box(&self) -> Box<dyn ClonableAny> {
|
||||||
|
Box::new(self.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The platform-independent part of the config needed to launch an application.
|
||||||
|
pub struct CrossPlatformConfig<F: ComponentFunction<P>, P> {
|
||||||
|
/// The root component function.
|
||||||
|
pub component: F,
|
||||||
|
/// The props for the root component.
|
||||||
|
pub props: P,
|
||||||
|
/// The contexts to provide to the root component.
|
||||||
|
pub root_contexts: Vec<Box<dyn ClonableAny>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PlatformBuilder<P> {
|
||||||
|
type Config;
|
||||||
|
|
||||||
|
/// Launch the app.
|
||||||
|
fn launch<F: ComponentFunction<P>>(config: CrossPlatformConfig<F, P>, config: Self::Config);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P> PlatformBuilder<P> for () {
|
||||||
|
type Config = ();
|
||||||
|
|
||||||
|
fn launch<F: ComponentFunction<P>>(config: CrossPlatformConfig<F, P>, _: ()) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A builder for a fullstack app.
|
||||||
|
pub struct LaunchBuilder<F: ComponentFunction<P>, P> {
|
||||||
|
cross_platform_config: CrossPlatformConfig<F, P>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F: ComponentFunction<P>, P> LaunchBuilder<F, P> {
|
||||||
|
/// Create a new builder for your application.
|
||||||
|
pub fn new(component: F) -> Self
|
||||||
|
where
|
||||||
|
P: Default,
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
cross_platform_config: CrossPlatformConfig {
|
||||||
|
component,
|
||||||
|
props: Default::default(),
|
||||||
|
root_contexts: vec![],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pass some props to your application.
|
||||||
|
pub fn props(mut self, props: P) -> Self {
|
||||||
|
self.cross_platform_config.props = props;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inject state into the root component's context.
|
||||||
|
pub fn context(mut self, state: impl ClonableAny + 'static) -> Self {
|
||||||
|
self.cross_platform_config
|
||||||
|
.root_contexts
|
||||||
|
.push(Box::new(state));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provide a platform-specific config to the builder.
|
||||||
|
pub fn platform_config(
|
||||||
|
self,
|
||||||
|
config: Option<<CurrentPlatform as PlatformBuilder<P>>::Config>,
|
||||||
|
) -> Self {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Launch the app.
|
||||||
|
pub fn launch(self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "router")]
|
||||||
|
impl<R: Routable> LaunchBuilder<crate::router::FullstackRouterConfig<R>>
|
||||||
|
where
|
||||||
|
<R as std::str::FromStr>::Err: std::fmt::Display,
|
||||||
|
R: Clone + serde::Serialize + serde::de::DeserializeOwned + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
/// Create a new launch builder for the given router.
|
||||||
|
pub fn router() -> Self {
|
||||||
|
let component = crate::router::RouteWithCfg::<R>;
|
||||||
|
let props = crate::router::FullstackRouterConfig::default();
|
||||||
|
Self::new_with_props(component, props)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type CurrentPlatform = ();
|
|
@ -2,7 +2,12 @@
|
||||||
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")]
|
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")]
|
||||||
#![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")]
|
#![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")]
|
||||||
|
|
||||||
pub use dioxus_core as core;
|
pub use dioxus_core;
|
||||||
|
|
||||||
|
#[cfg(feature = "launch")]
|
||||||
|
mod launch;
|
||||||
|
#[cfg(feature = "launch")]
|
||||||
|
pub use launch::*;
|
||||||
|
|
||||||
#[cfg(feature = "hooks")]
|
#[cfg(feature = "hooks")]
|
||||||
pub use dioxus_hooks as hooks;
|
pub use dioxus_hooks as hooks;
|
||||||
|
@ -37,6 +42,9 @@ pub mod prelude {
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub use dioxus_core_macro::{component, format_args_f, inline_props, render, rsx, Props};
|
pub use dioxus_core_macro::{component, format_args_f, inline_props, render, rsx, Props};
|
||||||
|
|
||||||
|
#[cfg(feature = "launch")]
|
||||||
|
pub use dioxus_config_macro::*;
|
||||||
|
|
||||||
#[cfg(feature = "html")]
|
#[cfg(feature = "html")]
|
||||||
pub use dioxus_html as dioxus_elements;
|
pub use dioxus_html as dioxus_elements;
|
||||||
|
|
||||||
|
@ -45,4 +53,6 @@ pub mod prelude {
|
||||||
|
|
||||||
#[cfg(all(not(target_arch = "wasm32"), feature = "hot-reload"))]
|
#[cfg(all(not(target_arch = "wasm32"), feature = "hot-reload"))]
|
||||||
pub use dioxus_hot_reload::{self, hot_reload_init};
|
pub use dioxus_hot_reload::{self, hot_reload_init};
|
||||||
|
|
||||||
|
pub use dioxus_core;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,9 @@ tower-http = { version = "0.4.0", optional = true, features = ["fs", "compressio
|
||||||
salvo = { version = "0.63.0", optional = true, features = ["serve-static", "websocket", "compression"] }
|
salvo = { version = "0.63.0", optional = true, features = ["serve-static", "websocket", "compression"] }
|
||||||
http-body-util = { version = "0.1.0-rc.2", optional = true }
|
http-body-util = { version = "0.1.0-rc.2", optional = true }
|
||||||
|
|
||||||
|
dioxus-core = { workspace = true }
|
||||||
|
|
||||||
# Dioxus + SSR
|
# Dioxus + SSR
|
||||||
dioxus = { workspace = true }
|
|
||||||
dioxus-ssr = { workspace = true, optional = true }
|
dioxus-ssr = { workspace = true, optional = true }
|
||||||
hyper = { version = "0.14.25", optional = true }
|
hyper = { version = "0.14.25", optional = true }
|
||||||
http = { version = "0.2.9", optional = true }
|
http = { version = "0.2.9", optional = true }
|
||||||
|
@ -67,7 +68,6 @@ dioxus-hot-reload = { workspace = true }
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
web-sys = { version = "0.3.61", features = ["Window", "Document", "Element", "HtmlDocument", "Storage", "console"] }
|
web-sys = { version = "0.3.61", features = ["Window", "Document", "Element", "HtmlDocument", "Storage", "console"] }
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["hot-reload"]
|
default = ["hot-reload"]
|
||||||
router = ["dioxus-router"]
|
router = ["dioxus-router"]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus_core::prelude::*;
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Launch helper macros for fullstack apps
|
//! Launch helper macros for fullstack apps
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use dioxus::prelude::*;
|
use dioxus_core::prelude::*;
|
||||||
#[cfg(feature = "router")]
|
#[cfg(feature = "router")]
|
||||||
use dioxus_router::prelude::*;
|
use dioxus_router::prelude::*;
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,6 @@ where
|
||||||
{
|
{
|
||||||
use dioxus_router::prelude::RouterConfig;
|
use dioxus_router::prelude::RouterConfig;
|
||||||
|
|
||||||
#[cfg(feature = "ssr")]
|
|
||||||
let context = crate::prelude::server_context();
|
|
||||||
|
|
||||||
let cfg = props;
|
let cfg = props;
|
||||||
render! {
|
render! {
|
||||||
dioxus_router::prelude::Router::<R> {
|
dioxus_router::prelude::Router::<R> {
|
||||||
|
@ -23,8 +20,9 @@ where
|
||||||
.history({
|
.history({
|
||||||
#[cfg(feature = "ssr")]
|
#[cfg(feature = "ssr")]
|
||||||
let history = dioxus_router::prelude::MemoryHistory::with_initial_path(
|
let history = dioxus_router::prelude::MemoryHistory::with_initial_path(
|
||||||
context
|
crate::prelude::server_context()
|
||||||
.request_parts().unwrap()
|
.request_parts()
|
||||||
|
.unwrap()
|
||||||
.uri
|
.uri
|
||||||
.to_string()
|
.to_string()
|
||||||
.parse()
|
.parse()
|
||||||
|
@ -44,7 +42,7 @@ where
|
||||||
);
|
);
|
||||||
history
|
history
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,6 @@ rocket_ws = { version = "0.1.0", optional = true }
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_env_logger = { version = "0.5.0" }
|
pretty_env_logger = { version = "0.5.0" }
|
||||||
tokio = { workspace = true, features = ["full"] }
|
tokio = { workspace = true, features = ["full"] }
|
||||||
dioxus = { workspace = true }
|
|
||||||
warp = "0.3.3"
|
warp = "0.3.3"
|
||||||
axum = { version = "0.6.1", features = ["ws"] }
|
axum = { version = "0.6.1", features = ["ws"] }
|
||||||
salvo = { version = "0.63.0", features = ["affix", "websocket"] }
|
salvo = { version = "0.63.0", features = ["affix", "websocket"] }
|
||||||
|
|
|
@ -189,7 +189,7 @@ fn create_random_dynamic_node(, depth: usize) -> DynamicNode {
|
||||||
node_paths: &[&[0]],
|
node_paths: &[&[0]],
|
||||||
attr_paths: &[],
|
attr_paths: &[],
|
||||||
}),
|
}),
|
||||||
dioxus::core::exports::bumpalo::collections::Vec::new_in(cx.bump()).into(),
|
dioxus::dioxus_core::exports::bumpalo::collections::Vec::new_in(cx.bump()).into(),
|
||||||
cx.bump().alloc([cx.component(
|
cx.bump().alloc([cx.component(
|
||||||
create_random_element,
|
create_random_element,
|
||||||
DepthProps { depth, root: false },
|
DepthProps { depth, root: false },
|
||||||
|
@ -260,7 +260,7 @@ fn create_random_element(cx: Scope<DepthProps>) -> Element {
|
||||||
None.into(),
|
None.into(),
|
||||||
None,
|
None,
|
||||||
Cell::new(template),
|
Cell::new(template),
|
||||||
dioxus::core::exports::bumpalo::collections::Vec::new_in(cx.bump()).into(),
|
dioxus::dioxus_core::exports::bumpalo::collections::Vec::new_in(cx.bump()).into(),
|
||||||
{
|
{
|
||||||
let dynamic_nodes: Vec<_> = dynamic_node_types
|
let dynamic_nodes: Vec<_> = dynamic_node_types
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -10,7 +10,7 @@ homepage = "https://dioxuslabs.com"
|
||||||
keywords = ["dom", "ui", "gui", "react", "wasm"]
|
keywords = ["dom", "ui", "gui", "react", "wasm"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dioxus = { workspace = true }
|
dioxus-lib = { workspace = true }
|
||||||
dioxus-router-macro = { workspace = true }
|
dioxus-router-macro = { workspace = true }
|
||||||
gloo = { version = "0.8.0", optional = true }
|
gloo = { version = "0.8.0", optional = true }
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
use crate::hooks::use_router;
|
use crate::hooks::use_router;
|
||||||
use dioxus::prelude::*;
|
use dioxus_lib::prelude::*;
|
||||||
|
|
||||||
/// The default component to render when an external navigation fails.
|
/// The default component to render when an external navigation fails.
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
@ -14,11 +14,6 @@ pub fn FailureExternalNavigation() -> Element {
|
||||||
"The application tried to programmatically navigate to an external page. This "
|
"The application tried to programmatically navigate to an external page. This "
|
||||||
"operation has failed. Click the link below to complete the navigation manually."
|
"operation has failed. Click the link below to complete the navigation manually."
|
||||||
}
|
}
|
||||||
a {
|
a { onclick: move |_| { router.clear_error() }, "Click here to go back" }
|
||||||
onclick: move |_| {
|
|
||||||
router.clear_error()
|
|
||||||
},
|
|
||||||
"Click here to go back"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus_lib::prelude::*;
|
||||||
|
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
use crate::utils::use_router_internal::use_router_internal;
|
use crate::utils::use_router_internal::use_router_internal;
|
||||||
|
@ -76,12 +77,7 @@ pub fn GoBackButton(
|
||||||
let disabled = !router.can_go_back();
|
let disabled = !router.can_go_back();
|
||||||
|
|
||||||
render! {
|
render! {
|
||||||
button {
|
button { disabled: "{disabled}", prevent_default: "onclick", onclick: move |_| router.go_back(), {children} }
|
||||||
disabled: "{disabled}",
|
|
||||||
prevent_default: "onclick",
|
|
||||||
onclick: move |_| router.go_back(),
|
|
||||||
{children}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,11 +147,6 @@ pub fn GoForwardButton(
|
||||||
let disabled = !router.can_go_forward();
|
let disabled = !router.can_go_forward();
|
||||||
|
|
||||||
render! {
|
render! {
|
||||||
button {
|
button { disabled: "{disabled}", prevent_default: "onclick", onclick: move |_| router.go_forward(), {children} }
|
||||||
disabled: "{disabled}",
|
|
||||||
prevent_default: "onclick",
|
|
||||||
onclick: move |_| router.go_forward(),
|
|
||||||
{children}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,8 @@ use std::any::Any;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus_lib::prelude::*;
|
||||||
|
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
use crate::navigation::NavigationTarget;
|
use crate::navigation::NavigationTarget;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::prelude::{outlet::OutletContext, *};
|
use crate::prelude::{outlet::OutletContext, *};
|
||||||
use dioxus::prelude::*;
|
use dioxus_lib::prelude::*;
|
||||||
|
|
||||||
/// An outlet for the current content.
|
/// An outlet for the current content.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus_lib::prelude::*;
|
||||||
|
|
||||||
use std::{cell::RefCell, str::FromStr};
|
use std::{cell::RefCell, str::FromStr};
|
||||||
|
|
||||||
use crate::{prelude::Outlet, routable::Routable, router_cfg::RouterConfig};
|
use crate::{prelude::Outlet, routable::Routable, router_cfg::RouterConfig};
|
||||||
|
@ -142,9 +143,7 @@ where
|
||||||
// _marker: std::marker::PhantomData,
|
// _marker: std::marker::PhantomData,
|
||||||
// });
|
// });
|
||||||
|
|
||||||
render! {
|
render! { Outlet::<R> {} }
|
||||||
Outlet::<R> {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
|
@ -169,7 +168,5 @@ where
|
||||||
_marker: std::marker::PhantomData,
|
_marker: std::marker::PhantomData,
|
||||||
});
|
});
|
||||||
|
|
||||||
render! {
|
render! { Outlet::<R> {} }
|
||||||
Outlet::<R> {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::prelude::{ExternalNavigationFailure, IntoRoutable, RouterContext};
|
||||||
/// Panics if there is no router present.
|
/// Panics if there is no router present.
|
||||||
pub fn navigator() -> Navigator {
|
pub fn navigator() -> Navigator {
|
||||||
Navigator(
|
Navigator(
|
||||||
dioxus::core::prelude::consume_context::<RouterContext>()
|
dioxus_lib::prelude::consume_context::<RouterContext>()
|
||||||
.expect("A router must be present to use navigator"),
|
.expect("A router must be present to use navigator"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus_lib::prelude::*;
|
||||||
|
|
||||||
use crate::{routable::Routable, utils::use_router_internal::use_router_internal};
|
use crate::{routable::Routable, utils::use_router_internal::use_router_internal};
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::{
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus_lib::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
navigation::NavigationTarget,
|
navigation::NavigationTarget,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use dioxus::prelude::{consume_context, use_hook};
|
use dioxus_lib::prelude::{consume_context, use_hook};
|
||||||
|
|
||||||
use crate::prelude::{Navigator, RouterContext};
|
use crate::prelude::{Navigator, RouterContext};
|
||||||
|
|
||||||
|
|
|
@ -9,5 +9,5 @@ pub fn use_router() -> RouterContext {
|
||||||
|
|
||||||
/// Aquire the router without subscribing to updates.
|
/// Aquire the router without subscribing to updates.
|
||||||
pub fn router() -> RouterContext {
|
pub fn router() -> RouterContext {
|
||||||
dioxus::core::prelude::consume_context().unwrap()
|
dioxus_lib::prelude::consume_context().unwrap()
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ pub mod prelude {
|
||||||
type Props;
|
type Props;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P> HasProps for dioxus::prelude::Component<P> {
|
impl<P> HasProps for dioxus_lib::prelude::Component<P> {
|
||||||
type Props = P;
|
type Props = P;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! # Routable
|
//! # Routable
|
||||||
|
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
use dioxus::prelude::*;
|
use dioxus_lib::prelude::*;
|
||||||
|
|
||||||
use std::iter::FlatMap;
|
use std::iter::FlatMap;
|
||||||
use std::slice::Iter;
|
use std::slice::Iter;
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::sync::Arc;
|
||||||
use crate::contexts::router::RoutingCallback;
|
use crate::contexts::router::RoutingCallback;
|
||||||
use crate::history::HistoryProvider;
|
use crate::history::HistoryProvider;
|
||||||
use crate::routable::Routable;
|
use crate::routable::Routable;
|
||||||
use dioxus::prelude::*;
|
use dioxus_lib::prelude::*;
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use dioxus::prelude::ScopeId;
|
use dioxus_lib::prelude::ScopeId;
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ impl ToTokens for ElementAttrNamed {
|
||||||
let value = quote! { #value };
|
let value = quote! { #value };
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
::dioxus::core::Attribute::new(
|
dioxus_core::Attribute::new(
|
||||||
#attribute,
|
#attribute,
|
||||||
#value,
|
#value,
|
||||||
#ns,
|
#ns,
|
||||||
|
|
|
@ -101,7 +101,7 @@ impl ToTokens for Component {
|
||||||
let fn_name = self.fn_name();
|
let fn_name = self.fn_name();
|
||||||
|
|
||||||
tokens.append_all(quote! {
|
tokens.append_all(quote! {
|
||||||
::dioxus::core::DynamicNode::Component(::dioxus::core::VComponent::new(
|
dioxus_core::DynamicNode::Component(dioxus_core::VComponent::new(
|
||||||
#name #prop_gen_args,
|
#name #prop_gen_args,
|
||||||
#builder,
|
#builder,
|
||||||
#fn_name
|
#fn_name
|
||||||
|
|
|
@ -280,7 +280,7 @@ impl ToTokens for Element {
|
||||||
});
|
});
|
||||||
|
|
||||||
tokens.append_all(quote! {
|
tokens.append_all(quote! {
|
||||||
::dioxus::core::Element::new(
|
dioxus_core::Element::new(
|
||||||
#name,
|
#name,
|
||||||
vec![ #(#listeners),* ],
|
vec![ #(#listeners),* ],
|
||||||
vec![ #(#attr),* ],
|
vec![ #(#attr),* ],
|
||||||
|
|
|
@ -85,7 +85,7 @@ impl CallBody {
|
||||||
};
|
};
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
::dioxus::core::LazyNodes::new( move | __cx: &::dioxus::core::ScopeState| -> ::dioxus::core::VNode {
|
dioxus_core::LazyNodes::new( move | __cx: &dioxus_core::ScopeState| -> dioxus_core::VNode {
|
||||||
#body
|
#body
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ impl ToTokens for CallBody {
|
||||||
};
|
};
|
||||||
|
|
||||||
out_tokens.append_all(quote! {
|
out_tokens.append_all(quote! {
|
||||||
::dioxus::core::LazyNodes::new( move | __cx: &::dioxus::core::ScopeState| -> ::dioxus::core::VNode {
|
dioxus_core::LazyNodes::new( move | __cx: &dioxus_core::ScopeState| -> dioxus_core::VNode {
|
||||||
#body
|
#body
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -246,14 +246,14 @@ impl<'a> ToTokens for TemplateRenderer<'a> {
|
||||||
let attr_paths = context.attr_paths.iter().map(|it| quote!(&[#(#it),*]));
|
let attr_paths = context.attr_paths.iter().map(|it| quote!(&[#(#it),*]));
|
||||||
|
|
||||||
out_tokens.append_all(quote! {
|
out_tokens.append_all(quote! {
|
||||||
static TEMPLATE: ::dioxus::core::Template = ::dioxus::core::Template {
|
static TEMPLATE: dioxus_core::Template = dioxus_core::Template {
|
||||||
name: #name,
|
name: #name,
|
||||||
roots: &[ #roots ],
|
roots: &[ #roots ],
|
||||||
node_paths: &[ #(#node_paths),* ],
|
node_paths: &[ #(#node_paths),* ],
|
||||||
attr_paths: &[ #(#attr_paths),* ],
|
attr_paths: &[ #(#attr_paths),* ],
|
||||||
};
|
};
|
||||||
|
|
||||||
::dioxus::core::VNode::new(
|
dioxus_core::VNode::new(
|
||||||
#key_tokens,
|
#key_tokens,
|
||||||
TEMPLATE,
|
TEMPLATE,
|
||||||
Box::new([ #( #node_printer),* ]),
|
Box::new([ #( #node_printer),* ]),
|
||||||
|
@ -491,7 +491,7 @@ impl<'a> DynamicContext<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
quote! {
|
quote! {
|
||||||
::dioxus::core::TemplateAttribute::Static {
|
dioxus_core::TemplateAttribute::Static {
|
||||||
name: #name,
|
name: #name,
|
||||||
namespace: #ns,
|
namespace: #ns,
|
||||||
value: #value,
|
value: #value,
|
||||||
|
@ -515,7 +515,7 @@ impl<'a> DynamicContext<'a> {
|
||||||
let ct = self.dynamic_attributes.len();
|
let ct = self.dynamic_attributes.len();
|
||||||
self.dynamic_attributes.push(vec![attr]);
|
self.dynamic_attributes.push(vec![attr]);
|
||||||
self.attr_paths.push(self.current_path.clone());
|
self.attr_paths.push(self.current_path.clone());
|
||||||
quote! { ::dioxus::core::TemplateAttribute::Dynamic { id: #ct }, }
|
quote! { dioxus_core::TemplateAttribute::Dynamic { id: #ct }, }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -536,7 +536,7 @@ impl<'a> DynamicContext<'a> {
|
||||||
let el_name = el_name.tag_name();
|
let el_name = el_name.tag_name();
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
::dioxus::core::TemplateNode::Element {
|
dioxus_core::TemplateNode::Element {
|
||||||
tag: #el_name,
|
tag: #el_name,
|
||||||
namespace: #ns,
|
namespace: #ns,
|
||||||
attrs: &[ #attrs ],
|
attrs: &[ #attrs ],
|
||||||
|
@ -547,7 +547,7 @@ impl<'a> DynamicContext<'a> {
|
||||||
|
|
||||||
BodyNode::Text(text) if text.is_static() => {
|
BodyNode::Text(text) if text.is_static() => {
|
||||||
let text = text.to_static().unwrap();
|
let text = text.to_static().unwrap();
|
||||||
quote! { ::dioxus::core::TemplateNode::Text{ text: #text } }
|
quote! { dioxus_core::TemplateNode::Text{ text: #text } }
|
||||||
}
|
}
|
||||||
|
|
||||||
BodyNode::RawExpr(_)
|
BodyNode::RawExpr(_)
|
||||||
|
@ -561,9 +561,9 @@ impl<'a> DynamicContext<'a> {
|
||||||
|
|
||||||
match root {
|
match root {
|
||||||
BodyNode::Text(_) => {
|
BodyNode::Text(_) => {
|
||||||
quote! { ::dioxus::core::TemplateNode::DynamicText { id: #ct } }
|
quote! { dioxus_core::TemplateNode::DynamicText { id: #ct } }
|
||||||
}
|
}
|
||||||
_ => quote! { ::dioxus::core::TemplateNode::Dynamic { id: #ct } },
|
_ => quote! { dioxus_core::TemplateNode::Dynamic { id: #ct } },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,7 @@ impl ToTokens for BodyNode {
|
||||||
BodyNode::Element(el) => el.to_tokens(tokens),
|
BodyNode::Element(el) => el.to_tokens(tokens),
|
||||||
BodyNode::Component(comp) => comp.to_tokens(tokens),
|
BodyNode::Component(comp) => comp.to_tokens(tokens),
|
||||||
BodyNode::Text(txt) => tokens.append_all(quote! {
|
BodyNode::Text(txt) => tokens.append_all(quote! {
|
||||||
::dioxus::core::DynamicNode::Text(::dioxus::core::VText::new(#txt))
|
dioxus_core::DynamicNode::Text(dioxus_core::VText::new(#txt))
|
||||||
}),
|
}),
|
||||||
BodyNode::RawExpr(exp) => tokens.append_all(quote! {
|
BodyNode::RawExpr(exp) => tokens.append_all(quote! {
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue