Fix the router and stub out a number of crates to get compiling

This commit is contained in:
Jonathan Kelley committed 2024-01-13 20:51:37 -08:00
1 parent 4c6e515da4
commit fae0b08e61
226 files changed
+1057 -1482

No files matched your search

+2 -2
View File
@@ -5,8 +5,8 @@ pub fn Explainer<'a>(
cx: Scope<'a>,
invert: bool,
title: &'static str,
content: Element<'a>,
flasher: Element<'a>,
content: Element,
flasher: Element,
) -> Element {
// pt-5 sm:pt-24 lg:pt-24
@@ -1,4 +1,4 @@
fn SaveClipboard(cx: Scope) -> Element {
fn SaveClipboard() -> Element {
rsx! {
div { class: "relative w-1/2 {align} max-w-md leading-8",
h2 { class: "mb-6 text-3xl leading-tight md:text-4xl md:leading-tight lg:text-3xl lg:leading-tight font-heading font-mono font-bold",
+1 -1
View File
@@ -1,3 +1,3 @@
fn app(cx: Scope) -> Element {
fn app() -> Element {
cx.render(rsx! { div { "hello world" } })
}
@@ -1,4 +1,4 @@
fn app(cx: Scope) -> Element {
fn app() -> Element {
cx.render(rsx! {
div {"hello world" }
})
+1 -1
View File
@@ -1,3 +1,3 @@
fn app(cx: Scope) -> Element {
fn app() -> Element {
cx.render(rsx! { div { "hello world" } })
}
@@ -1,4 +1,4 @@
fn app(cx: Scope) -> Element {
fn app() -> Element {
cx.render(rsx! {
div {"hello world" }
})
+38 -38
View File
@@ -279,7 +279,7 @@ mod tests {
#[test]
fn test_no_hooks() {
let contents = indoc! {r#"
fn App(cx: Scope) -> Element {
fn App() -> Element {
rsx! {
p { "Hello World" }
}
@@ -294,8 +294,8 @@ mod tests {
#[test]
fn test_hook_correctly_used_inside_component() {
let contents = indoc! {r#"
fn App(cx: Scope) -> Element {
let count = use_state(cx, || 0);
fn App() -> Element {
let count = use_state(|| 0);
rsx! {
p { "Hello World: {count}" }
}
@@ -310,8 +310,8 @@ mod tests {
#[test]
fn test_hook_correctly_used_inside_hook_fn() {
let contents = indoc! {r#"
fn use_thing(cx: Scope) -> UseState<i32> {
use_state(cx, || 0)
fn use_thing() -> UseState<i32> {
use_state(|| 0)
}
"#};
@@ -323,9 +323,9 @@ mod tests {
#[test]
fn test_hook_correctly_used_inside_hook_closure() {
let contents = indoc! {r#"
fn App(cx: Scope) -> Element {
fn App() -> Element {
let use_thing = || {
use_state(cx, || 0)
use_state(|| 0)
};
let count = use_thing();
rsx! {
@@ -342,9 +342,9 @@ mod tests {
#[test]
fn test_conditional_hook_if() {
let contents = indoc! {r#"
fn App(cx: Scope) -> Element {
fn App() -> Element {
if you_are_happy && you_know_it {
let something = use_state(cx, || "hands");
let something = use_state(|| "hands");
println!("clap your {something}")
}
}
@@ -357,7 +357,7 @@ mod tests {
vec![Issue::HookInsideConditional(
HookInfo::new(
Span::new_from_str(
r#"use_state(cx, || "hands")"#,
r#"use_state(|| "hands")"#,
LineColumn { line: 3, column: 24 },
),
Span::new_from_str(
@@ -368,7 +368,7 @@ mod tests {
),
ConditionalInfo::If(IfInfo::new(
Span::new_from_str(
"if you_are_happy && you_know_it {\n let something = use_state(cx, || \"hands\");\n println!(\"clap your {something}\")\n }",
"if you_are_happy && you_know_it {\n let something = use_state(|| \"hands\");\n println!(\"clap your {something}\")\n }",
LineColumn { line: 2, column: 4 },
),
Span::new_from_str(
@@ -383,10 +383,10 @@ mod tests {
#[test]
fn test_conditional_hook_match() {
let contents = indoc! {r#"
fn App(cx: Scope) -> Element {
fn App() -> Element {
match you_are_happy && you_know_it {
true => {
let something = use_state(cx, || "hands");
let something = use_state(|| "hands");
println!("clap your {something}")
}
false => {}
@@ -400,13 +400,13 @@ mod tests {
report.issues,
vec![Issue::HookInsideConditional(
HookInfo::new(
Span::new_from_str(r#"use_state(cx, || "hands")"#, LineColumn { line: 4, column: 28 }),
Span::new_from_str(r#"use_state(|| "hands")"#, LineColumn { line: 4, column: 28 }),
Span::new_from_str(r#"use_state"#, LineColumn { line: 4, column: 28 }),
"use_state".to_string()
),
ConditionalInfo::Match(MatchInfo::new(
Span::new_from_str(
"match you_are_happy && you_know_it {\n true => {\n let something = use_state(cx, || \"hands\");\n println!(\"clap your {something}\")\n }\n false => {}\n }",
"match you_are_happy && you_know_it {\n true => {\n let something = use_state(|| \"hands\");\n println!(\"clap your {something}\")\n }\n false => {}\n }",
LineColumn { line: 2, column: 4 },
),
Span::new_from_str("match you_are_happy && you_know_it", LineColumn { line: 2, column: 4 })
@@ -418,9 +418,9 @@ mod tests {
#[test]
fn test_for_loop_hook() {
let contents = indoc! {r#"
fn App(cx: Scope) -> Element {
fn App() -> Element {
for _name in &names {
let is_selected = use_state(cx, || false);
let is_selected = use_state(|| false);
println!("selected: {is_selected}");
}
}
@@ -433,7 +433,7 @@ mod tests {
vec![Issue::HookInsideLoop(
HookInfo::new(
Span::new_from_str(
"use_state(cx, || false)",
"use_state(|| false)",
LineColumn { line: 3, column: 26 },
),
Span::new_from_str(
@@ -444,7 +444,7 @@ mod tests {
),
AnyLoopInfo::For(ForInfo::new(
Span::new_from_str(
"for _name in &names {\n let is_selected = use_state(cx, || false);\n println!(\"selected: {is_selected}\");\n }",
"for _name in &names {\n let is_selected = use_state(|| false);\n println!(\"selected: {is_selected}\");\n }",
LineColumn { line: 2, column: 4 },
),
Span::new_from_str(
@@ -459,9 +459,9 @@ mod tests {
#[test]
fn test_while_loop_hook() {
let contents = indoc! {r#"
fn App(cx: Scope) -> Element {
fn App() -> Element {
while true {
let something = use_state(cx, || "hands");
let something = use_state(|| "hands");
println!("clap your {something}")
}
}
@@ -474,7 +474,7 @@ mod tests {
vec![Issue::HookInsideLoop(
HookInfo::new(
Span::new_from_str(
r#"use_state(cx, || "hands")"#,
r#"use_state(|| "hands")"#,
LineColumn { line: 3, column: 24 },
),
Span::new_from_str(
@@ -485,7 +485,7 @@ mod tests {
),
AnyLoopInfo::While(WhileInfo::new(
Span::new_from_str(
"while true {\n let something = use_state(cx, || \"hands\");\n println!(\"clap your {something}\")\n }",
"while true {\n let something = use_state(|| \"hands\");\n println!(\"clap your {something}\")\n }",
LineColumn { line: 2, column: 4 },
),
Span::new_from_str(
@@ -500,9 +500,9 @@ mod tests {
#[test]
fn test_loop_hook() {
let contents = indoc! {r#"
fn App(cx: Scope) -> Element {
fn App() -> Element {
loop {
let something = use_state(cx, || "hands");
let something = use_state(|| "hands");
println!("clap your {something}")
}
}
@@ -515,7 +515,7 @@ mod tests {
vec![Issue::HookInsideLoop(
HookInfo::new(
Span::new_from_str(
r#"use_state(cx, || "hands")"#,
r#"use_state(|| "hands")"#,
LineColumn { line: 3, column: 24 },
),
Span::new_from_str(
@@ -525,7 +525,7 @@ mod tests {
"use_state".to_string()
),
AnyLoopInfo::Loop(LoopInfo::new(Span::new_from_str(
"loop {\n let something = use_state(cx, || \"hands\");\n println!(\"clap your {something}\")\n }",
"loop {\n let something = use_state(|| \"hands\");\n println!(\"clap your {something}\")\n }",
LineColumn { line: 2, column: 4 },
)))
)],
@@ -535,8 +535,8 @@ mod tests {
#[test]
fn test_conditional_okay() {
let contents = indoc! {r#"
fn App(cx: Scope) -> Element {
let something = use_state(cx, || "hands");
fn App() -> Element {
let something = use_state(|| "hands");
if you_are_happy && you_know_it {
println!("clap your {something}")
}
@@ -551,9 +551,9 @@ mod tests {
#[test]
fn test_closure_hook() {
let contents = indoc! {r#"
fn App(cx: Scope) -> Element {
fn App() -> Element {
let _a = || {
let b = use_state(cx, || 0);
let b = use_state(|| 0);
b.get()
};
}
@@ -566,7 +566,7 @@ mod tests {
vec![Issue::HookInsideClosure(
HookInfo::new(
Span::new_from_str(
"use_state(cx, || 0)",
"use_state(|| 0)",
LineColumn {
line: 3,
column: 16
@@ -582,7 +582,7 @@ mod tests {
"use_state".to_string()
),
ClosureInfo::new(Span::new_from_str(
"|| {\n let b = use_state(cx, || 0);\n b.get()\n }",
"|| {\n let b = use_state(|| 0);\n b.get()\n }",
LineColumn {
line: 2,
column: 13
@@ -595,8 +595,8 @@ mod tests {
#[test]
fn test_hook_outside_component() {
let contents = indoc! {r#"
fn not_component_or_hook(cx: Scope) {
let _a = use_state(cx, || 0);
fn not_component_or_hook() {
let _a = use_state(|| 0);
}
"#};
@@ -606,7 +606,7 @@ mod tests {
report.issues,
vec![Issue::HookOutsideComponent(HookInfo::new(
Span::new_from_str(
"use_state(cx, || 0)",
"use_state(|| 0)",
LineColumn {
line: 2,
column: 13
@@ -627,8 +627,8 @@ mod tests {
#[test]
fn test_hook_inside_hook() {
let contents = indoc! {r#"
fn use_thing(cx: Scope) {
let _a = use_state(cx, || 0);
fn use_thing() {
let _a = use_state(|| 0);
}
"#};
+21 -21
View File
@@ -230,9 +230,9 @@ mod tests {
let issue_report = check_file(
"src/main.rs".into(),
indoc! {r#"
fn App(cx: Scope) -> Element {
fn App() -> Element {
if you_are_happy && you_know_it {
let something = use_state(cx, || "hands");
let something = use_state(|| "hands");
println!("clap your {something}")
}
}
@@ -243,7 +243,7 @@ mod tests {
error: hook called conditionally: `use_state` (inside `if`)
--> src/main.rs:3:25
|
3 | let something = use_state(cx, || "hands");
3 | let something = use_state(|| "hands");
| ^^^^^^^^^
|
= note: `if you_are_happy && you_know_it { … }` is the conditional
@@ -258,10 +258,10 @@ mod tests {
let issue_report = check_file(
"src/main.rs".into(),
indoc! {r#"
fn App(cx: Scope) -> Element {
fn App() -> Element {
match you_are_happy && you_know_it {
true => {
let something = use_state(cx, || "hands");
let something = use_state(|| "hands");
println!("clap your {something}")
}
_ => {}
@@ -274,7 +274,7 @@ mod tests {
error: hook called conditionally: `use_state` (inside `match`)
--> src/main.rs:4:29
|
4 | let something = use_state(cx, || "hands");
4 | let something = use_state(|| "hands");
| ^^^^^^^^^
|
= note: `match you_are_happy && you_know_it { … }` is the conditional
@@ -289,9 +289,9 @@ mod tests {
let issue_report = check_file(
"src/main.rs".into(),
indoc! {r#"
fn App(cx: Scope) -> Element {
fn App() -> Element {
for i in 0..10 {
let something = use_state(cx, || "hands");
let something = use_state(|| "hands");
println!("clap your {something}")
}
}
@@ -302,7 +302,7 @@ mod tests {
error: hook called in a loop: `use_state` (inside `for` loop)
--> src/main.rs:3:25
|
3 | let something = use_state(cx, || "hands");
3 | let something = use_state(|| "hands");
| ^^^^^^^^^
|
= note: `for i in 0..10 { … }` is the loop
@@ -317,9 +317,9 @@ mod tests {
let issue_report = check_file(
"src/main.rs".into(),
indoc! {r#"
fn App(cx: Scope) -> Element {
fn App() -> Element {
while check_thing() {
let something = use_state(cx, || "hands");
let something = use_state(|| "hands");
println!("clap your {something}")
}
}
@@ -330,7 +330,7 @@ mod tests {
error: hook called in a loop: `use_state` (inside `while` loop)
--> src/main.rs:3:25
|
3 | let something = use_state(cx, || "hands");
3 | let something = use_state(|| "hands");
| ^^^^^^^^^
|
= note: `while check_thing() { … }` is the loop
@@ -345,9 +345,9 @@ mod tests {
let issue_report = check_file(
"src/main.rs".into(),
indoc! {r#"
fn App(cx: Scope) -> Element {
fn App() -> Element {
loop {
let something = use_state(cx, || "hands");
let something = use_state(|| "hands");
println!("clap your {something}")
}
}
@@ -358,7 +358,7 @@ mod tests {
error: hook called in a loop: `use_state` (inside `loop`)
--> src/main.rs:3:25
|
3 | let something = use_state(cx, || "hands");
3 | let something = use_state(|| "hands");
| ^^^^^^^^^
|
= note: `loop { … }` is the loop
@@ -373,9 +373,9 @@ mod tests {
let issue_report = check_file(
"src/main.rs".into(),
indoc! {r#"
fn App(cx: Scope) -> Element {
fn App() -> Element {
let something = || {
let something = use_state(cx, || "hands");
let something = use_state(|| "hands");
println!("clap your {something}")
};
}
@@ -386,7 +386,7 @@ mod tests {
error: hook called in a closure: `use_state`
--> src/main.rs:3:25
|
3 | let something = use_state(cx, || "hands");
3 | let something = use_state(|| "hands");
| ^^^^^^^^^
"#};
@@ -399,9 +399,9 @@ mod tests {
let issue_report = check_file(
"src/main.rs".into(),
indoc! {r#"
fn App(cx: Scope) -> Element {
fn App() -> Element {
if you_are_happy && you_know_it {
let something = use_state(cx, || {
let something = use_state(|| {
"hands"
});
println!("clap your {something}")
@@ -414,7 +414,7 @@ mod tests {
error: hook called conditionally: `use_state` (inside `if`)
--> src/main.rs:3:25
|
3 | let something = use_state(cx, || {
3 | let something = use_state(|| {
| ^^^^^^^^^
4 | "hands"
5 | });
+1 -1
View File
@@ -3,7 +3,7 @@
pub struct HookInfo {
/// The name of the hook, e.g. `use_state`.
pub name: String,
/// The span of the hook, e.g. `use_state(cx, || 0)`.
/// The span of the hook, e.g. `use_state(|| 0)`.
pub span: Span,
/// The span of the name, e.g. `use_state`.
pub name_span: Span,
+2 -2
View File
@@ -71,7 +71,7 @@ fn write_callbody_with_icon_section(mut callbody: CallBody) -> String {
}
fn write_component_body(raw: String) -> String {
let mut out = String::from("fn component(cx: Scope) -> Element {\n cx.render(rsx! {");
let mut out = String::from("fn component() -> Element {\n cx.render(rsx! {");
indent_and_write(&raw, 1, &mut out);
out.push_str(" })\n}");
out
@@ -84,7 +84,7 @@ fn write_svg_section(out: &mut String, svgs: Vec<BodyNode>) {
let raw = dioxus_autofmt::write_block_out(CallBody { roots: vec![icon] }).unwrap();
out.push_str("\n\n pub fn icon_");
out.push_str(&idx.to_string());
out.push_str("(cx: Scope) -> Element {\n cx.render(rsx! {");
out.push_str("() -> Element {\n cx.render(rsx! {");
indent_and_write(&raw, 2, out);
out.push_str(" })\n }");
}
+2 -2
View File
@@ -36,7 +36,7 @@ async fn setup_file_watcher<F: Fn() -> Result<BuildResult> + Send + 'static>(
if let Some(hot_reload) = &hot_reload {
// find changes to the rsx in the file
let mut rsx_file_map = hot_reload.file_map.lock().unwrap();
let mut messages: Vec<Template<'static>> = Vec::new();
let mut messages: Vec<Template> = Vec::new();
// In hot reload mode, we only need to rebuild if non-rsx code is changed
needs_full_rebuild = false;
@@ -143,6 +143,6 @@ pub(crate) trait Platform {
#[derive(Clone)]
pub struct HotReloadState {
pub messages: broadcast::Sender<Template<'static>>,
pub messages: broadcast::Sender<Template>,
pub file_map: Arc<Mutex<FileMap<HtmlCtx>>>,
}
@@ -66,11 +66,11 @@
//! use dioxus::prelude::*;
//!
//! #[name_changer(CoolName)]
//! pub fn LameName(cx: Scope) -> Element {
//! pub fn LameName() -> Element {
//! render! { "I want a cool name!" }
//! }
//!
//! pub fn App(cx: Scope) -> Element {
//! pub fn App() -> Element {
//! render! { CoolName {} } // Renders: "I want a cool name!"
//! }
//! ```
+7 -7
View File
@@ -65,7 +65,7 @@ pub fn render(s: TokenStream) -> TokenStream {
/// # Example
/// ```rust,ignore
/// #[inline_props]
/// fn app(cx: Scope, bob: String) -> Element {
/// fn app(bob: String) -> Element {
/// cx.render(rsx!("hello, {bob}"))
/// }
///
@@ -128,17 +128,17 @@ pub(crate) const COMPONENT_ARG_CASE_CHECK_OFF: &str = "no_case_check";
/// * Without props:
/// ```rust,ignore
/// #[component]
/// fn GreetBob(cx: Scope) -> Element {
/// fn GreetBob() -> Element {
/// render! { "hello, bob" }
/// }
///
/// // is equivalent to
///
/// #[allow(non_snake_case)]
/// fn GreetBob(cx: Scope) -> Element {
/// fn GreetBob() -> Element {
/// #[warn(non_snake_case)]
/// #[inline(always)]
/// fn __dx_inner_comp(cx: Scope) -> Element {
/// fn __dx_inner_comp() -> Element {
/// render! { "hello, bob" }
/// }
/// // There's no function call overhead since __dx_inner_comp has the #[inline(always)] attribute,
@@ -149,7 +149,7 @@ pub(crate) const COMPONENT_ARG_CASE_CHECK_OFF: &str = "no_case_check";
/// * With props:
/// ```rust,ignore
/// #[component(no_case_check)]
/// fn GreetPerson(cx: Scope, person: String) -> Element {
/// fn GreetPerson(person: String) -> Element {
/// render! { "hello, {person}" }
/// }
///
@@ -162,10 +162,10 @@ pub(crate) const COMPONENT_ARG_CASE_CHECK_OFF: &str = "no_case_check";
/// }
///
/// #[allow(non_snake_case)]
/// fn GreetPerson<'a>(cx: Scope<'a, GreetPersonProps>) -> Element {
/// fn GreetPerson(props: GreetPersonProps>) -> Element {
/// #[warn(non_snake_case)]
/// #[inline(always)]
/// fn __dx_inner_comp<'a>(cx: Scope<'a, GreetPersonProps>e) -> Element {
/// fn __dx_inner_comp(props: GreetPersonProps>e) -> Element {
/// let GreetPersonProps { person } = &cx.props;
/// {
/// render! { "hello, {person}" }
+4
View File
@@ -99,6 +99,10 @@ pub fn once<State: Clone + 'static>(initializer: impl FnOnce() -> State) -> Stat
with_current_scope(|cx| cx.use_hook(initializer)).expect("to be in a dioxus runtime")
}
pub fn use_hook<State: Clone + 'static>(initializer: impl FnOnce() -> State) -> State {
once(initializer)
}
/// Get the current render since the inception of this component
///
/// This can be used as a helpful diagnostic when debugging hooks/renders, etc
+1 -1
View File
@@ -87,7 +87,7 @@ pub mod prelude {
consume_context, consume_context_from_scope, current_scope_id, fc_to_builder, generation,
has_context, needs_update, once, parent_scope, provide_context, provide_root_context,
push_future, remove_future, schedule_update, schedule_update_any, spawn, spawn_forever,
suspend, use_error_boundary, AnyValue, Component, Element, ErrorBoundary, Event,
suspend, use_error_boundary, use_hook, AnyValue, Component, Element, ErrorBoundary, Event,
EventHandler, Fragment, IntoAttributeValue, IntoDynNode, Properties, Runtime, RuntimeGuard,
ScopeId, Task, Template, TemplateAttribute, TemplateNode, Throw, VNode, VNodeInner,
VirtualDom,
+7 -4
View File
@@ -1,6 +1,9 @@
use crate::any_props::{BoxedAnyProps, VProps};
use crate::innerlude::{ElementRef, EventHandler, MountId, ScopeState};
use crate::innerlude::{ElementRef, EventHandler, MountId};
use crate::properties::ComponentFunction;
use crate::{
any_props::{BoxedAnyProps, VProps},
innerlude::ScopeState,
};
use crate::{arena::ElementId, Element, Event};
use crate::{Properties, VirtualDom};
use std::ops::Deref;
@@ -16,7 +19,7 @@ pub type TemplateId = &'static str;
/// The actual state of the component's most recent computation
///
/// Because Dioxus accepts components in the form of `async fn(Scope) -> Result<VNode>`, we need to support both
/// Because Dioxus accepts components in the form of `async fn() -> Result<VNode>`, we need to support both
/// sync and async versions.
///
/// Dioxus will do its best to immediately resolve any async components into a regular Element, but as an implementor
@@ -457,7 +460,7 @@ impl VComponent {
///
/// ```rust, ignore
/// // Without explicit props
/// fn(Scope) -> Element;
/// fn() -> Element;
/// async fn(Scope<'_>) -> Element;
///
/// // With explicit props
+2 -2
View File
@@ -1,9 +1,9 @@
use crate::{
any_props::{AnyProps, BoxedAnyProps},
innerlude::DirtyScope,
innerlude::{DirtyScope, ScopeState},
nodes::RenderReturn,
scope_context::ScopeContext,
scopes::{ScopeId, ScopeState},
scopes::ScopeId,
virtual_dom::VirtualDom,
};
+1 -1
View File
@@ -254,7 +254,7 @@ impl ScopeContext {
/// use dioxus_core::ScopeState;
///
/// // prints a greeting on the initial render
/// pub fn use_hello_world(cx: &ScopeState) {
/// pub fn use_hello_world() {
/// cx.use_hook(|| println!("Hello, world!"));
/// }
/// ```
+3 -3
View File
@@ -6,13 +6,13 @@ use crate::{
any_props::{BoxedAnyProps, VProps},
arena::ElementId,
innerlude::{
DirtyScope, ElementRef, ErrorBoundary, NoOpMutations, Scheduler, SchedulerMsg, VNodeMount,
WriteMutations,
DirtyScope, ElementRef, ErrorBoundary, NoOpMutations, Scheduler, SchedulerMsg, ScopeState,
VNodeMount, WriteMutations,
},
nodes::RenderReturn,
nodes::{Template, TemplateId},
runtime::{Runtime, RuntimeGuard},
scopes::{ScopeId, ScopeState},
scopes::ScopeId,
AttributeValue, Element, Event, MutationsVec,
};
use futures_util::{pin_mut, StreamExt};
+3 -3
View File
@@ -1,8 +1,8 @@
use dioxus::prelude::*;
fn app(cx: Scope) -> Element {
let state = use_state(cx, || 0);
use_future(cx, (), |_| {
fn app() -> Element {
let state = use_state(|| 0);
use_future((), |_| {
to_owned![state];
async move {
loop {
+4 -16
View File
@@ -28,10 +28,10 @@ pub fn main() {
check_app_exits(app);
}
fn mock_event(cx: &ScopeState, id: &'static str, value: &'static str) {
fn mock_event(id: &'static str, value: &'static str) {
let eval_provider = use_eval(cx).clone();
use_effect(cx, (), move |_| async move {
use_effect(move |_| async move {
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
let js = format!(
r#"
@@ -50,13 +50,12 @@ fn mock_event(cx: &ScopeState, id: &'static str, value: &'static str) {
}
#[allow(deprecated)]
fn app(cx: Scope) -> Element {
fn app() -> Element {
let desktop_context: DesktopContext = cx.consume_context().unwrap();
let received_events = use_state(cx, || 0);
let received_events = use_state(|| 0);
// button
mock_event(
cx,
"button",
r#"new MouseEvent("click", {
view: window,
@@ -67,7 +66,6 @@ fn app(cx: Scope) -> Element {
);
// mouse_move_div
mock_event(
cx,
"mouse_move_div",
r#"new MouseEvent("mousemove", {
view: window,
@@ -78,7 +76,6 @@ fn app(cx: Scope) -> Element {
);
// mouse_click_div
mock_event(
cx,
"mouse_click_div",
r#"new MouseEvent("click", {
view: window,
@@ -90,7 +87,6 @@ fn app(cx: Scope) -> Element {
);
// mouse_dblclick_div
mock_event(
cx,
"mouse_dblclick_div",
r#"new MouseEvent("dblclick", {
view: window,
@@ -102,7 +98,6 @@ fn app(cx: Scope) -> Element {
);
// mouse_down_div
mock_event(
cx,
"mouse_down_div",
r#"new MouseEvent("mousedown", {
view: window,
@@ -114,7 +109,6 @@ fn app(cx: Scope) -> Element {
);
// mouse_up_div
mock_event(
cx,
"mouse_up_div",
r#"new MouseEvent("mouseup", {
view: window,
@@ -126,7 +120,6 @@ fn app(cx: Scope) -> Element {
);
// wheel_div
mock_event(
cx,
"wheel_div",
r#"new WheelEvent("wheel", {
view: window,
@@ -139,7 +132,6 @@ fn app(cx: Scope) -> Element {
);
// key_down_div
mock_event(
cx,
"key_down_div",
r#"new KeyboardEvent("keydown", {
key: "a",
@@ -161,7 +153,6 @@ fn app(cx: Scope) -> Element {
);
// key_up_div
mock_event(
cx,
"key_up_div",
r#"new KeyboardEvent("keyup", {
key: "a",
@@ -183,7 +174,6 @@ fn app(cx: Scope) -> Element {
);
// key_press_div
mock_event(
cx,
"key_press_div",
r#"new KeyboardEvent("keypress", {
key: "a",
@@ -205,13 +195,11 @@ fn app(cx: Scope) -> Element {
);
// focus_in_div
mock_event(
cx,
"focus_in_div",
r#"new FocusEvent("focusin", {bubbles: true})"#,
);
// focus_out_div
mock_event(
cx,
"focus_out_div",
r#"new FocusEvent("focusout",{bubbles: true})"#,
);
+5 -5
View File
@@ -26,11 +26,11 @@ fn main() {
check_app_exits(check_html_renders);
}
fn use_inner_html(cx: &ScopeState, id: &'static str) -> Option<String> {
fn use_inner_html(d: &'static str) -> Option<String> {
let eval_provider = use_eval(cx);
let value: &UseRef<Option<String>> = use_ref(cx, || None);
use_effect(cx, (), |_| {
let value: &UseRef<Option<String>> = use_ref(|| None);
use_effect((), |_| {
to_owned![value, eval_provider];
async move {
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
@@ -51,8 +51,8 @@ fn use_inner_html(cx: &ScopeState, id: &'static str) -> Option<String> {
const EXPECTED_HTML: &str = r#"<div id="5" style="width: 100px; height: 100px; color: rgb(0, 0, 0);"><input type="checkbox"><h1>text</h1><div><p>hello world</p></div></div>"#;
fn check_html_renders(cx: Scope) -> Element {
let inner_html = use_inner_html(cx, "main_div");
fn check_html_renders() -> Element {
let inner_html = use_inner_html("main_div");
let desktop_context: DesktopContext = cx.consume_context().unwrap();
+1 -1
View File
@@ -125,7 +125,7 @@ impl EditQueue {
// }
// pub fn add_template(
// template: &Template<'static>,
// template: &Template,
// channel: &mut Channel,
// templates: &mut FxHashMap<String, u16>,
// max_template_count: &AtomicU16,
+4 -4
View File
@@ -6,7 +6,7 @@ use tao::{event::Event, event_loop::EventLoopWindowTarget};
use wry::RequestAsyncResponder;
// /// Get an imperative handle to the current window
// pub fn use_window(cx: &ScopeState) -> &DesktopContext {
// pub fn use_window() -> &DesktopContext {
// cx.use_hook(|| cx.consume_context::<DesktopContext>())
// .as_ref()
// .unwrap()
@@ -14,7 +14,7 @@ use wry::RequestAsyncResponder;
// /// Get a closure that executes any JavaScript in the WebView context.
// pub fn use_wry_event_handler(
// cx: &ScopeState,
// ,
// handler: impl FnMut(&Event<UserWindowEvent>, &EventLoopWindowTarget<UserWindowEvent>) + 'static,
// ) -> &WryEventHandler {
// cx.use_hook(move || {
@@ -34,7 +34,7 @@ use wry::RequestAsyncResponder;
// /// The callback takes a path as requested by the web view, and it should return `Some(response)`
// /// if you want to load the asset, and `None` if you want to fallback on the default behavior.
// pub fn use_asset_handler(
// cx: &ScopeState,
// ,
// name: &str,
// handler: impl Fn(AssetRequest, RequestAsyncResponder) + 'static,
// ) {
@@ -59,7 +59,7 @@ use wry::RequestAsyncResponder;
// /// Get a closure that executes any JavaScript in the WebView context.
// pub fn use_global_shortcut(
// cx: &ScopeState,
// ,
// accelerator: impl IntoAccelerator,
// handler: impl FnMut() + 'static,
// ) -> &Result<ShortcutHandle, ShortcutRegistryError> {
+2 -2
View File
@@ -17,7 +17,7 @@ use tao::event::{Event, StartCause, WindowEvent};
/// dioxus_desktop::launch(app);
/// }
///
/// fn app(cx: Scope) -> Element {
/// fn app() -> Element {
/// cx.render(rsx!{
/// h1 {"hello world!"}
/// })
@@ -41,7 +41,7 @@ pub fn launch(root: Component) {
/// dioxus_desktop::launch_cfg(app, Config::default().with_window(WindowBuilder::new().with_title("My App")));
/// }
///
/// fn app(cx: Scope) -> Element {
/// fn app() -> Element {
/// cx.render(rsx!{
/// h1 {"hello world!"}
/// })
+1 -1
View File
@@ -34,7 +34,7 @@ fn main() {
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
fn app() -> Element {
cx.render(rsx!{
div {
"hello world!"
+1 -1
View File
@@ -42,7 +42,7 @@
Leverage React-like patterns, CSS, HTML, and Rust to build beautiful, portable, terminal user interfaces with Dioxus.
```rust
fn app(cx: Scope) -> Element {
fn app() -> Element {
cx.render(rsx!{
div {
width: "100%",
+3 -3
View File
@@ -66,7 +66,7 @@ struct BoxProps {
}
#[allow(non_snake_case)]
fn Box(cx: Scope<BoxProps>) -> Element {
let count = use_state(cx, || 0);
let count = use_state(|| 0);
let x = cx.props.x * 2;
let y = cx.props.y * 2;
@@ -96,8 +96,8 @@ struct GridProps {
#[allow(non_snake_case)]
fn Grid(cx: Scope<GridProps>) -> Element {
let size = cx.props.size;
let count = use_state(cx, || 0);
let counts = use_ref(cx, || vec![0; size * size]);
let count = use_state(|| 0);
let counts = use_ref(|| vec![0; size * size]);
let ctx: TuiContext = cx.consume_context().unwrap();
if *count.get() + cx.props.update_count >= (size * size) {
@@ -26,8 +26,8 @@ enum Event {
const MAX_EVENTS: usize = 8;
fn app(cx: Scope) -> Element {
let events = use_ref(cx, Vec::new);
fn app() -> Element {
let events = use_ref(Vec::new);
let events_lock = events.read();
let first_index = events_lock.len().saturating_sub(MAX_EVENTS);
+2 -2
View File
@@ -4,8 +4,8 @@ fn main() {
dioxus_tui::launch(app);
}
fn app(cx: Scope) -> Element {
let radius = use_state(cx, || 0);
fn app() -> Element {
let radius = use_state(|| 0);
cx.render(rsx! {
div {
+3 -3
View File
@@ -13,8 +13,8 @@ struct ButtonProps {
#[allow(non_snake_case)]
fn Button(cx: Scope<ButtonProps>) -> Element {
let toggle = use_state(cx, || false);
let hovered = use_state(cx, || false);
let toggle = use_state(|| false);
let hovered = use_state(|| false);
let hue = cx.props.color_offset % 255;
let saturation = if *toggle.get() { 50 } else { 25 } + if *hovered.get() { 50 } else { 25 };
@@ -50,7 +50,7 @@ fn Button(cx: Scope<ButtonProps>) -> Element {
})
}
fn app(cx: Scope) -> Element {
fn app() -> Element {
cx.render(rsx! {
div {
display: "flex",
+1 -1
View File
@@ -7,7 +7,7 @@ fn main() {
);
}
fn app(cx: Scope) -> Element {
fn app() -> Element {
let steps = 50;
cx.render(rsx! {
div{
+3 -3
View File
@@ -8,9 +8,9 @@ fn main() {
dioxus_tui::launch(app);
}
fn app(cx: Scope) -> Element {
let hue = use_state(cx, || 0.0);
let brightness = use_state(cx, || 0.0);
fn app() -> Element {
let hue = use_state(|| 0.0);
let brightness = use_state(|| 0.0);
let tui_query: Query = cx.consume_context().unwrap();
let mapping: DioxusElementToNodeId = cx.consume_context().unwrap();
// disable templates so that every node has an id and can be queried
+1 -1
View File
@@ -4,7 +4,7 @@ fn main() {
dioxus_tui::launch(app);
}
fn app(cx: Scope) -> Element {
fn app() -> Element {
cx.render(rsx! {
div {
width: "100%",
+9 -9
View File
@@ -8,7 +8,7 @@ fn main() {
dioxus_tui::launch(app);
}
fn app(cx: Scope) -> Element {
fn app() -> Element {
fn to_str(c: &[i32; 3]) -> String {
let mut result = String::new();
result += "#";
@@ -23,20 +23,20 @@ fn app(cx: Scope) -> Element {
127 * b
}
let q1_color = use_state(cx, || [200; 3]);
let q2_color = use_state(cx, || [200; 3]);
let q3_color = use_state(cx, || [200; 3]);
let q4_color = use_state(cx, || [200; 3]);
let q1_color = use_state(|| [200; 3]);
let q2_color = use_state(|| [200; 3]);
let q3_color = use_state(|| [200; 3]);
let q4_color = use_state(|| [200; 3]);
let q1_color_str = to_str(q1_color);
let q2_color_str = to_str(q2_color);
let q3_color_str = to_str(q3_color);
let q4_color_str = to_str(q4_color);
let page_coordinates = use_state(cx, || "".to_string());
let element_coordinates = use_state(cx, || "".to_string());
let buttons = use_state(cx, || "".to_string());
let modifiers = use_state(cx, || "".to_string());
let page_coordinates = use_state(|| "".to_string());
let element_coordinates = use_state(|| "".to_string());
let buttons = use_state(|| "".to_string());
let modifiers = use_state(|| "".to_string());
let update_data = move |event: Event<MouseData>| {
let mouse_data = event.inner();
+1 -1
View File
@@ -4,7 +4,7 @@ fn main() {
dioxus_tui::launch(app);
}
fn app(cx: Scope) -> Element {
fn app() -> Element {
cx.render(rsx! {
div {
width: "100%",
@@ -19,7 +19,7 @@ struct BoxProps {
}
#[allow(non_snake_case)]
fn Box(cx: Scope<BoxProps>) -> Element {
let count = use_state(cx, || 0);
let count = use_state(|| 0);
let x = cx.props.x * 2;
let y = cx.props.y * 2;
@@ -48,8 +48,8 @@ struct GridProps {
#[allow(non_snake_case)]
fn Grid(cx: Scope<GridProps>) -> Element {
let size = cx.props.size;
let count = use_state(cx, || 0);
let counts = use_ref(cx, || vec![0; size * size]);
let count = use_state(|| 0);
let counts = use_ref(|| vec![0; size * size]);
let ctx: TuiContext = cx.consume_context().unwrap();
if *count.get() + 1 >= (size * size) {
+1 -1
View File
@@ -4,7 +4,7 @@ fn main() {
dioxus_tui::launch(app);
}
fn app(cx: Scope) -> Element {
fn app() -> Element {
cx.render(rsx! {
div {
width: "100%",
+1 -1
View File
@@ -28,7 +28,7 @@ fn Quadrant(cx: Scope<QuadrentProps>) -> Element {
})
}
fn app(cx: Scope) -> Element {
fn app() -> Element {
cx.render(rsx! {
div {
width: "100%",
@@ -4,7 +4,7 @@ fn main() {
dioxus_tui::launch(app);
}
fn app(cx: Scope) -> Element {
fn app() -> Element {
cx.render(rsx! {
div {
width: "100%",
+3 -3
View File
@@ -4,10 +4,10 @@ fn main() {
dioxus_tui::launch(app);
}
fn app(cx: Scope) -> Element {
let count = use_state(cx, || 0);
fn app() -> Element {
let count = use_state(|| 0);
use_future(cx, (), move |_| {
use_future((), move |_| {
let count = count.to_owned();
let update = cx.schedule_update();
async move {
+2 -2
View File
@@ -4,8 +4,8 @@ fn main() {
dioxus_tui::launch(app);
}
fn app(cx: Scope) -> Element {
let alpha = use_state(cx, || 100);
fn app() -> Element {
let alpha = use_state(|| 100);
cx.render(rsx! {
div {
+2 -2
View File
@@ -5,8 +5,8 @@ fn main() {
dioxus_tui::launch_cfg(app, Config::new());
}
fn app(cx: Scope) -> Element {
let bg_green = use_state(cx, || false);
fn app() -> Element {
let bg_green = use_state(|| false);
let color = if *bg_green.get() { "green" } else { "red" };
cx.render(rsx! {
+18 -18
View File
@@ -32,8 +32,8 @@ impl Future for PollN {
fn key_down() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app(cx: Scope) -> Element {
let render_count = use_state(cx, || 0);
fn app() -> Element {
let render_count = use_state(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap();
let render_count_handle = render_count.clone();
cx.spawn(async move {
@@ -73,8 +73,8 @@ fn key_down() {
fn mouse_down() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app(cx: Scope) -> Element {
let render_count = use_state(cx, || 0);
fn app() -> Element {
let render_count = use_state(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap();
let render_count_handle = render_count.clone();
cx.spawn(async move {
@@ -109,8 +109,8 @@ fn mouse_down() {
fn mouse_up() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app(cx: Scope) -> Element {
let render_count = use_state(cx, || 0);
fn app() -> Element {
let render_count = use_state(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap();
let render_count_handle = render_count.clone();
cx.spawn(async move {
@@ -148,8 +148,8 @@ fn mouse_up() {
fn mouse_enter() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app(cx: Scope) -> Element {
let render_count = use_state(cx, || 0);
fn app() -> Element {
let render_count = use_state(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap();
let render_count_handle = render_count.clone();
cx.spawn(async move {
@@ -187,8 +187,8 @@ fn mouse_enter() {
fn mouse_exit() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app(cx: Scope) -> Element {
let render_count = use_state(cx, || 0);
fn app() -> Element {
let render_count = use_state(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap();
let render_count_handle = render_count.clone();
cx.spawn(async move {
@@ -226,8 +226,8 @@ fn mouse_exit() {
fn mouse_move() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app(cx: Scope) -> Element {
let render_count = use_state(cx, || 0);
fn app() -> Element {
let render_count = use_state(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap();
let render_count_handle = render_count.clone();
cx.spawn(async move {
@@ -265,8 +265,8 @@ fn mouse_move() {
fn wheel() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app(cx: Scope) -> Element {
let render_count = use_state(cx, || 0);
fn app() -> Element {
let render_count = use_state(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap();
let render_count_handle = render_count.clone();
cx.spawn(async move {
@@ -305,8 +305,8 @@ fn wheel() {
fn click() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app(cx: Scope) -> Element {
let render_count = use_state(cx, || 0);
fn app() -> Element {
let render_count = use_state(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap();
let render_count_handle = render_count.clone();
cx.spawn(async move {
@@ -344,8 +344,8 @@ fn click() {
fn context_menu() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app(cx: Scope) -> Element {
let render_count = use_state(cx, || 0);
fn app() -> Element {
let render_count = use_state(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap();
let render_count_handle = render_count.clone();
cx.spawn(async move {
+13 -13
View File
@@ -49,7 +49,7 @@ fn main() {
// 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(cx: Scope) -> Element {
fn App() -> Element {
cx.render(rsx!("hello world!"))
}
```
@@ -98,7 +98,7 @@ render nodes in match statements.
```rust, ignore
#[component[
fn Example(cx: Scope) -> Element {
fn Example() -> Element {
// both of these are equivalent
cx.render(rsx!("hello world"))
@@ -112,7 +112,7 @@ elements:
```rust, ignore
#[component]
fn App(cx: Scope) -> Element {
fn App() -> Element {
let name = "dave";
cx.render(rsx!(
h1 { "Hello, {name}!" }
@@ -141,7 +141,7 @@ In Dioxus, all properties are memoized by default!
```rust, ignore
#[component]
fn App(cx: Scope) -> Element {
fn App() -> Element {
cx.render(rsx!(
Header {
title: "My App",
@@ -178,7 +178,7 @@ struct from function arguments:
```rust, ignore
#[component]
fn Header(cx: Scope, title: String, color: String) -> Element {
fn Header(title: String, color: String) -> Element {
cx.render(rsx!(
div {
background_color: "{color}"
@@ -201,7 +201,7 @@ struct HeaderProps<'a> {
}
#[component]
fn Header<'a>(cx: Scope<'a, HeaderProps<'a>>) -> Element {
fn Header(props: HeaderProps -> Element {
cx.render(rsx!(
div {
background_color: "{cx.props.color}"
@@ -243,8 +243,8 @@ use hooks to define the state and modify it from within listeners.
```rust, ignore
#[component]
fn App(cx: Scope) -> Element {
let name = use_state(cx, || "world");
fn App() -> Element {
let name = use_state(|| "world");
render!("hello {name}!")
}
@@ -264,8 +264,8 @@ 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(cx: &ScopeState, id: Uuid) -> bool {
let users = use_context::<Users>(cx);
fn use_username(d: Uuid) -> bool {
let users = use_context::<Users>();
users.get(&id).map(|user| user.logged_in).ok_or(false)
}
```
@@ -273,7 +273,7 @@ fn use_username(cx: &ScopeState, id: Uuid) -> bool {
To create entirely new foundational hooks, we can use the `use_hook` method on `ScopeState`.
```rust, ignore
fn use_mut_string(cx: &ScopeState) -> &mut String {
fn use_mut_string() -> &mut String {
cx.use_hook(|_| "Hello".to_string())
}
```
@@ -292,8 +292,8 @@ fn main() {
}
#[component]
fn App(cx: Scope) -> Element {
let count = use_state(cx, || 0);
fn App() -> Element {
let count = use_state(|| 0);
cx.render(rsx!(
div { "Count: {count}" }
+26 -23
View File
@@ -25,42 +25,45 @@ criterion_group!(mbenches, create_rows);
criterion_main!(mbenches);
fn create_rows(c: &mut Criterion) {
fn app(cx: Scope) -> Element {
let mut rng = SmallRng::from_entropy();
render!(
table {
tbody {
(0..10_000_usize).map(|f| {
let label = Label::new(&mut rng);
rsx!( Row { row_id: f, label: label } )
})
}
}
)
}
c.bench_function("create rows", |b| {
let mut dom = VirtualDom::new(app);
let _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
b.iter(|| {
let g = dom.rebuild();
let g = dom.rebuild(&mut ());
assert!(g.edits.len() > 1);
})
});
}
#[derive(PartialEq, Props)]
fn app() -> Element {
let mut rng = SmallRng::from_entropy();
rsx! (
table {
tbody {
for f in 0..10_000_usize {
table_row {
row_id: f,
label: Label::new(&mut rng)
}
}
}
}
)
}
#[derive(PartialEq, Props, Clone, Copy)]
struct RowProps {
row_id: usize,
label: Label,
}
fn Row(cx: Scope<RowProps>) -> Element {
let [adj, col, noun] = cx.props.label.0;
cx.render(rsx! {
fn table_row(props: RowProps) -> Element {
let [adj, col, noun] = props.label.0;
rsx! {
tr {
td { class:"col-md-1", "{cx.props.row_id}" }
td { class:"col-md-1", "{props.row_id}" }
td { class:"col-md-1", onclick: move |_| { /* run onselect */ },
a { class: "lbl", "{adj}" "{col}" "{noun}" }
}
@@ -71,10 +74,10 @@ fn Row(cx: Scope<RowProps>) -> Element {
}
td { class: "col-md-6" }
}
})
}
}
#[derive(PartialEq)]
#[derive(PartialEq, Clone, Copy)]
struct Label([&'static str; 3]);
impl Label {
-103
View File
@@ -1,103 +0,0 @@
use dioxus::prelude::*;
use rand::prelude::*;
fn main() {
let mut dom = VirtualDom::new(app);
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
for _ in 0..1000 {
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
}
}
fn app(cx: Scope) -> Element {
let mut rng = SmallRng::from_entropy();
cx.render(rsx! (
table {
tbody {
for f in 0..10_000_usize {
table_row {
row_id: f,
label: Label::new(&mut rng)
}
}
}
}
))
}
#[derive(PartialEq, Props)]
struct RowProps {
row_id: usize,
label: Label,
}
fn table_row(cx: Scope<RowProps>) -> Element {
let [adj, col, noun] = cx.props.label.0;
cx.render(rsx! {
tr {
td { class:"col-md-1", "{cx.props.row_id}" }
td { class:"col-md-1", onclick: move |_| { /* run onselect */ },
a { class: "lbl", "{adj}" "{col}" "{noun}" }
}
td { class: "col-md-1",
a { class: "remove", onclick: move |_| {/* remove */},
span { class: "glyphicon glyphicon-remove remove", aria_hidden: "true" }
}
}
td { class: "col-md-6" }
}
})
}
#[derive(PartialEq)]
struct Label([&'static str; 3]);
impl Label {
fn new(rng: &mut SmallRng) -> Self {
Label([
ADJECTIVES.choose(rng).unwrap(),
COLOURS.choose(rng).unwrap(),
NOUNS.choose(rng).unwrap(),
])
}
}
static ADJECTIVES: &[&str] = &[
"pretty",
"large",
"big",
"small",
"tall",
"short",
"long",
"handsome",
"plain",
"quaint",
"clean",
"elegant",
"easy",
"angry",
"crazy",
"helpful",
"mushy",
"odd",
"unsightly",
"adorable",
"important",
"inexpensive",
"cheap",
"expensive",
"fancy",
];
static COLOURS: &[&str] = &[
"red", "yellow", "blue", "green", "pink", "brown", "purple", "brown", "white", "black",
"orange",
];
static NOUNS: &[&str] = &[
"table", "chair", "house", "bbq", "desk", "car", "pony", "cookie", "sandwich", "burger",
"pizza", "mouse", "keyboard",
];
+6 -6
View File
@@ -41,8 +41,8 @@ static NAME: Atom<&str> = Atom(|_| "Dioxus");
From anywhere in our app, we can read the value of our atom:
```rust, ignore
fn NameCard(cx: Scope) -> Element {
let name = use_read(cx, &NAME);
fn NameCard() -> Element {
let name = use_read(&NAME);
cx.render(rsx!{ h1 { "Hello, {name}"} })
}
```
@@ -50,8 +50,8 @@ fn NameCard(cx: Scope) -> Element {
We can also set the value of our atom, also from anywhere in our app:
```rust, ignore
fn NameCard(cx: Scope) -> Element {
let set_name = use_set(cx, &NAME);
fn NameCard() -> Element {
let set_name = use_set(&NAME);
cx.render(rsx!{
button {
onclick: move |_| set_name("Fermi"),
@@ -66,8 +66,8 @@ If needed, we can update the atom's value, based on itself:
```rust, ignore
static COUNT: Atom<i32> = Atom(|_| 0);
fn Counter(cx: Scope) -> Element {
let mut count = use_atom_state(cx, &COUNT);
fn Counter() -> Element {
let mut count = use_atom_state(&COUNT);
cx.render(rsx!{
p {
+1 -1
View File
@@ -29,7 +29,7 @@ impl CallbackApi {
}
#[must_use]
pub fn use_atom_context(cx: &ScopeState) -> &CallbackApi {
pub fn use_atom_context() -> &CallbackApi {
todo!()
}
+4 -4
View File
@@ -1,5 +1,5 @@
use crate::{use_atom_root, AtomId, AtomRef, AtomRoot, Readable};
use dioxus_core::{ScopeId, ScopeState};
use dioxus_core::ScopeId;
use std::{
cell::{Ref, RefCell, RefMut},
rc::Rc,
@@ -101,14 +101,14 @@ impl<T: 'static> UseAtomRef<T> {
/// Example:
/// ```ignore
/// static ATOM_DATA: AtomRef<Collection> = |_| Default::default();
/// fn App(cx: Scope) {
/// fn App() {
/// use_init_atom_root(cx);
/// let atom_data = use_atom_ref(cx, ATOM_DATA);
/// let atom_data = use_atom_ref(ATOM_DATA);
/// atom_data.unsubscribe(cx);
/// atom_data.write().update();
/// }
/// ```
pub fn unsubscribe(&self, cx: &ScopeState) {
pub fn unsubscribe(&self) {
self.root.unsubscribe(self.ptr, cx.scope_id());
}
+1 -1
View File
@@ -4,7 +4,7 @@ use crate::AtomRoot;
use dioxus_core::ScopeState;
// Returns the atom root, initiaizing it at the root of the app if it does not exist.
pub fn use_atom_root(cx: &ScopeState) -> &Rc<AtomRoot> {
pub fn use_atom_root() -> &Rc<AtomRoot> {
cx.use_hook(|| match cx.consume_context::<Rc<AtomRoot>>() {
Some(root) => root,
None => panic!("No atom root found in context. Did you forget to call use_init_atom_root at the top of your app?"),
+1 -1
View File
@@ -3,7 +3,7 @@ use dioxus_core::ScopeState;
use std::rc::Rc;
// Initializes the atom root and retuns it;
pub fn use_init_atom_root(cx: &ScopeState) -> &Rc<AtomRoot> {
pub fn use_init_atom_root() -> &Rc<AtomRoot> {
cx.use_hook(|| match cx.consume_context::<Rc<AtomRoot>>() {
Some(ctx) => ctx,
None => cx.provide_context(Rc::new(AtomRoot::new(cx.schedule_update_any()))),
+4 -4
View File
@@ -1,14 +1,14 @@
use crate::{use_atom_root, AtomId, AtomRoot, Readable};
use dioxus_core::{ScopeId, ScopeState};
use dioxus_core::ScopeId;
use std::rc::Rc;
#[must_use]
pub fn use_read<V: 'static>(cx: &ScopeState, f: impl Readable<V>) -> &V {
use_read_rc(cx, f).as_ref()
pub fn use_read<V: 'static>(f: impl Readable<V>) -> &V {
use_read_rc(f).as_ref()
}
#[must_use]
pub fn use_read_rc<V: 'static>(cx: &ScopeState, f: impl Readable<V>) -> &Rc<V> {
pub fn use_read_rc<V: 'static>(f: impl Readable<V>) -> &Rc<V> {
let root = use_atom_root(cx);
struct UseReadInner<V> {
+1 -1
View File
@@ -3,7 +3,7 @@ use dioxus_core::ScopeState;
use std::rc::Rc;
#[must_use]
pub fn use_set<T: 'static>(cx: &ScopeState, f: impl Writable<T>) -> &Rc<dyn Fn(T)> {
pub fn use_set<T: 'static>(f: impl Writable<T>) -> &Rc<dyn Fn(T)> {
let root = use_atom_root(cx);
cx.use_hook(|| {
let id = f.unique_id();
+16 -16
View File
@@ -1,5 +1,5 @@
use crate::{AtomId, AtomRoot, Writable};
use dioxus_core::{ScopeId, ScopeState};
use dioxus_core::ScopeId;
use std::{
cell::RefMut,
fmt::{Debug, Display},
@@ -18,8 +18,8 @@ use std::{
/// ```ignore
/// static COUNT: Atom<u32> = |_| 0;
///
/// fn Example(cx: Scope) -> Element {
/// let mut count = use_atom_state(cx, &COUNT);
/// fn Example() -> Element {
/// let mut count = use_atom_state(&COUNT);
///
/// cx.render(rsx! {
/// div {
@@ -31,7 +31,7 @@ use std::{
/// }
/// ```
#[must_use]
pub fn use_atom_state<T: 'static>(cx: &ScopeState, f: impl Writable<T>) -> &AtomState<T> {
pub fn use_atom_state<T: 'static>(f: impl Writable<T>) -> &AtomState<T> {
let root = crate::use_atom_root(cx);
let inner = cx.use_hook(|| AtomState {
@@ -74,8 +74,8 @@ impl<T: 'static> AtomState<T> {
/// An async context might need to know the current value:
///
/// ```rust, ignore
/// fn component(cx: Scope) -> Element {
/// let count = use_state(cx, || 0);
/// fn component() -> Element {
/// let count = use_state(|| 0);
/// cx.spawn({
/// let set_count = count.to_owned();
/// async move {
@@ -103,8 +103,8 @@ impl<T: 'static> AtomState<T> {
/// A component might require an `Rc<dyn Fn(T)>` as an input to set a value.
///
/// ```rust, ignore
/// fn component(cx: Scope) -> Element {
/// let value = use_state(cx, || 0);
/// fn component() -> Element {
/// let value = use_state(|| 0);
///
/// rsx!{
/// Component {
@@ -130,8 +130,8 @@ impl<T: 'static> AtomState<T> {
/// ```rust, ignore
/// # use dioxus_core::prelude::*;
/// # use dioxus_hooks::*;
/// fn component(cx: Scope) -> Element {
/// let value = use_state(cx, || 0);
/// fn component() -> Element {
/// let value = use_state(|| 0);
///
/// // to increment the value
/// value.modify(|v| v + 1);
@@ -170,8 +170,8 @@ impl<T: 'static> AtomState<T> {
/// ```rust, ignore
/// # use dioxus_core::prelude::*;
/// # use dioxus_hooks::*;
/// fn component(cx: Scope) -> Element {
/// let value = use_state(cx, || 0);
/// fn component() -> Element {
/// let value = use_state(|| 0);
///
/// let as_rc = value.get();
/// assert_eq!(as_rc.as_ref(), &0);
@@ -192,8 +192,8 @@ impl<T: 'static> AtomState<T> {
/// Mark all consumers of this atom to re-render
///
/// ```rust, ignore
/// fn component(cx: Scope) -> Element {
/// let count = use_state(cx, || 0);
/// fn component() -> Element {
/// let count = use_state(|| 0);
/// cx.spawn({
/// let count = count.to_owned();
/// async move {
@@ -223,7 +223,7 @@ impl<T: Clone> AtomState<T> {
/// # Examples
///
/// ```ignore
/// let val = use_state(cx, || 0);
/// let val = use_state(|| 0);
///
/// val.with_mut(|v| *v = 1);
/// ```
@@ -246,7 +246,7 @@ impl<T: Clone> AtomState<T> {
/// # Examples
///
/// ```ignore
/// let val = use_state(cx, || 0);
/// let val = use_state(|| 0);
///
/// *val.make_mut() += 1;
/// ```
+2 -2
View File
@@ -62,8 +62,8 @@ fn main() {
}
}
fn app(cx: Scope) -> Element {
let meaning = use_state(cx, || None);
fn app() -> Element {
let meaning = use_state(|| None);
cx.render(rsx! {
button {
onclick: move |_| {
@@ -74,9 +74,9 @@ fn main() {
}
}
//
fn app(cx: Scope) -> Element {
let user_name = use_state(cx, || "?".to_string());
let permissions = use_state(cx, || "?".to_string());
fn app() -> Element {
let user_name = use_state(|| "?".to_string());
let permissions = use_state(|| "?".to_string());
cx.render(rsx! {
div {
@@ -2,9 +2,9 @@
use dioxus::prelude::*;
use dioxus_fullstack::prelude::*;
pub fn app(cx: Scope) -> Element {
let mut count = use_state(cx, || 0);
let text = use_state(cx, || "...".to_string());
pub fn app() -> Element {
let mut count = use_state(|| 0);
let text = use_state(|| "...".to_string());
cx.render(rsx! {
h1 { "High-Five counter: {count}" }
@@ -20,10 +20,10 @@ struct AppProps {
fn app(cx: Scope<AppProps>) -> Element {
let state =
use_server_future(cx, (), |()| async move { get_server_data().await.unwrap() })?.value();
use_server_future((), |()| async move { get_server_data().await.unwrap() })?.value();
let mut count = use_state(cx, || 0);
let text = use_state(cx, || "...".to_string());
let mut count = use_state(|| 0);
let text = use_state(|| "...".to_string());
let eval = use_eval(cx);
cx.render(rsx! {
@@ -32,7 +32,7 @@ enum Route {
}
#[component]
fn Blog(cx: Scope, id: i32) -> Element {
fn Blog(id: i32) -> Element {
render! {
Link { to: Route::Home {}, "Go to counter" }
table {
@@ -50,9 +50,9 @@ fn Blog(cx: Scope, id: i32) -> Element {
}
#[component]
fn Home(cx: Scope) -> Element {
let mut count = use_state(cx, || 0);
let text = use_state(cx, || "...".to_string());
fn Home() -> Element {
let mut count = use_state(|| 0);
let text = use_state(|| "...".to_string());
cx.render(rsx! {
Link {
@@ -17,10 +17,10 @@ struct AppProps {
fn app(cx: Scope<AppProps>) -> Element {
let state =
use_server_future(cx, (), |()| async move { get_server_data().await.unwrap() })?.value();
use_server_future((), |()| async move { get_server_data().await.unwrap() })?.value();
let mut count = use_state(cx, || 0);
let text = use_state(cx, || "...".to_string());
let mut count = use_state(|| 0);
let text = use_state(|| "...".to_string());
cx.render(rsx! {
div {
@@ -50,7 +50,7 @@ enum Route {
}
#[component]
fn Blog(cx: Scope) -> Element {
fn Blog() -> Element {
render! {
Link { to: Route::Home {}, "Go to counter" }
table {
@@ -68,9 +68,9 @@ fn Blog(cx: Scope) -> Element {
}
#[component]
fn Home(cx: Scope) -> Element {
let mut count = use_state(cx, || 0);
let text = use_state(cx, || "...".to_string());
fn Home() -> Element {
let mut count = use_state(|| 0);
let text = use_state(|| "...".to_string());
cx.render(rsx! {
Link {
@@ -17,10 +17,10 @@ struct AppProps {
fn app(cx: Scope<AppProps>) -> Element {
let state =
use_server_future(cx, (), |()| async move { get_server_data().await.unwrap() })?.value();
use_server_future((), |()| async move { get_server_data().await.unwrap() })?.value();
let mut count = use_state(cx, || 0);
let text = use_state(cx, || "...".to_string());
let mut count = use_state(|| 0);
let text = use_state(|| "...".to_string());
cx.render(rsx! {
div {
@@ -29,8 +29,8 @@
//! }
//! }
//!
//! fn app(cx: Scope) -> Element {
//! let text = use_state(cx, || "...".to_string());
//! fn app() -> Element {
//! let text = use_state(|| "...".to_string());
//!
//! cx.render(rsx! {
//! button {
@@ -182,7 +182,7 @@ pub trait DioxusRouterExt<S> {
/// .unwrap();
/// }
///
/// fn app(cx: Scope) -> Element {
/// fn app() -> Element {
/// todo!()
/// }
/// ```
@@ -211,7 +211,7 @@ pub trait DioxusRouterExt<S> {
/// .unwrap();
/// }
///
/// fn app(cx: Scope) -> Element {
/// fn app() -> Element {
/// todo!()
/// }
/// ```
@@ -379,7 +379,7 @@ fn apply_request_parts_to_response<B>(
/// use dioxus::prelude::*;
/// use dioxus_fullstack::{axum_adapter::render_handler_with_context, prelude::*};
///
/// fn app(cx: Scope) -> Element {
/// fn app() -> Element {
/// render! {
/// "hello!"
/// }
@@ -24,8 +24,8 @@
//! }
//! }
//!
//! fn app(cx: Scope) -> Element {
//! let text = use_state(cx, || "...".to_string());
//! fn app() -> Element {
//! let text = use_state(|| "...".to_string());
//!
//! cx.render(rsx! {
//! button {
@@ -199,7 +199,7 @@ pub trait DioxusRouterExt {
/// .await;
/// }
///
/// fn app(cx: Scope) -> Element {todo!()}
/// fn app() -> Element {todo!()}
/// ```
fn serve_dioxus_application<P: Clone + serde::Serialize + Send + Sync + 'static>(
self,
@@ -20,8 +20,8 @@
//! }
//! }
//!
//! fn app(cx: Scope) -> Element {
//! let text = use_state(cx, || "...".to_string());
//! fn app() -> Element {
//! let text = use_state(|| "...".to_string());
//!
//! cx.render(rsx! {
//! button {
@@ -175,7 +175,7 @@ pub fn register_server_fns(server_fn_route: &'static str) -> BoxedFilter<(impl R
/// warp::serve(routes).run(([127, 0, 0, 1], 8080)).await;
/// }
///
/// fn app(cx: Scope) -> Element {
/// fn app() -> Element {
/// todo!()
/// }
/// ```
@@ -11,8 +11,8 @@ use serde::{de::DeserializeOwned, Serialize};
/// use dioxus::prelude::*;
/// use dioxus_fullstack::prelude::*;
///
/// fn app(cx: Scope) -> Element {
/// let state1 = server_cached(cx, || from_server(|| {
/// fn app() -> Element {
/// let state1 = server_cached(|| from_server(|| {
/// 1234
/// }));
///
@@ -24,7 +24,6 @@ use std::sync::Arc;
/// - dependencies: a tuple of references to values that are PartialEq + Clone
#[must_use = "Consider using `cx.spawn` to run a future without reading its value"]
pub fn use_server_future<T, F, D>(
cx: &ScopeState,
dependencies: D,
future: impl FnOnce(D::Out) -> F,
) -> Option<&UseServerFuture<T>>
@@ -128,7 +127,7 @@ impl<T> UseServerFuture<T> {
}
/// Forcefully cancel a future
pub fn cancel(&self, cx: &ScopeState) {
pub fn cancel(&self) {
if let Some(task) = self.task.take() {
cx.remove_future(task);
}
+2 -3
View File
@@ -9,10 +9,9 @@ use tokio::sync::{
#[derive(Clone)]
pub struct HotReloadState {
// The cache of all templates that have been modified since the last time we checked
pub(crate) templates:
Arc<RwLock<std::collections::HashSet<dioxus::prelude::Template<'static>>>>,
pub(crate) templates: Arc<RwLock<std::collections::HashSet<dioxus::prelude::Template>>>,
// The channel to send messages to the hot reload thread
pub(crate) message_receiver: Receiver<Option<Template<'static>>>,
pub(crate) message_receiver: Receiver<Option<Template>>,
}
impl Default for HotReloadState {
+2 -2
View File
@@ -49,7 +49,7 @@ where
}
}
fn default_external_navigation_handler() -> fn(Scope) -> Element {
fn default_external_navigation_handler() -> fn() -> Element {
dioxus_router::prelude::FailureExternalNavigation
}
@@ -62,7 +62,7 @@ where
{
#[serde(skip)]
#[serde(default = "default_external_navigation_handler")]
failure_external_navigation: fn(Scope) -> Element,
failure_external_navigation: fn() -> Element,
scroll_restoration: bool,
#[serde(skip)]
phantom: std::marker::PhantomData<R>,
+10 -11
View File
@@ -1,6 +1,6 @@
//! Tracked and computed state in Dioxus
use dioxus_core::{ScopeId, ScopeState};
use dioxus_core::{ScopeId};
use slab::Slab;
use std::{
cell::{RefCell, RefMut},
@@ -18,8 +18,8 @@ use std::{
/// use dioxus::prelude::*;
///
/// #[component]
/// fn Parent(cx: Scope) -> Element {
/// let count = use_tracked_state(cx, || 0);
/// fn Parent() -> Element {
/// let count = use_tracked_state(|| 0);
///
/// render! {
/// Child {
@@ -29,8 +29,8 @@ use std::{
/// }
///
/// #[component]
/// fn Child(cx: Scope, count: Tracked<usize>) -> Element {
/// let less_than_five = use_selector(cx, count, |count| *count < 5);
/// fn Child(count: Tracked<usize>) -> Element {
/// let less_than_five = use_selector(count, |count| *count < 5);
///
/// render! {
/// "{less_than_five}"
@@ -38,10 +38,10 @@ use std::{
/// }
/// ```
#[must_use]
pub fn use_tracked_state<T: 'static>(cx: &ScopeState, init: impl FnOnce() -> T) -> &Tracked<T> {
pub fn use_tracked_state<T: 'static>(nit: impl FnOnce() -> T) -> &Tracked<T> {
cx.use_hook(|| {
let init = init();
Tracked::new(cx, init)
Tracked::new(init)
})
}
@@ -63,7 +63,7 @@ impl<I: PartialEq> PartialEq for Tracked<I> {
impl<I> Tracked<I> {
/// Create a new tracked state
pub fn new(cx: &ScopeState, state: I) -> Self {
pub fn new(, state: I) -> Self {
let subscribers = std::rc::Rc::new(std::cell::RefCell::new(Slab::new()));
Self {
state: Rc::new(RefCell::new(state)),
@@ -162,8 +162,7 @@ impl<I> Drop for Tracker<I> {
}
#[must_use = "Consider using the `use_effect` hook to rerun an effect whenever the tracked state changes if you don't need the result of the computation"]
pub fn use_selector<I: 'static, O: Clone + PartialEq + 'static>(
cx: &ScopeState,
pub fn use_selector<I: 'static, O: Clone + PartialEq + 'static>
tracked: &Tracked<I>,
init: impl FnMut(&I) -> O + 'static,
) -> O {
@@ -189,7 +188,7 @@ impl<T, I> PartialEq for Selector<T, I> {
impl<T: Clone + PartialEq, I> Selector<T, I> {
/// Read the Selector state and subscribe to updates
pub fn use_state(&self, cx: &ScopeState) -> T {
pub fn use_state(&self, ) -> T {
cx.use_hook(|| {
let id = cx.scope_id();
self.subscribers.borrow_mut().insert(id);
+1 -1
View File
@@ -18,7 +18,7 @@
/// # }
/// # fn Component(cx: Scope<Props>) -> Element {
///
/// let (data) = use_ref(cx, || {});
/// let (data) = use_ref(|| {});
///
/// let handle_thing = move |_| {
/// to_owned![data, cx.props.prop];
+4 -4
View File
@@ -25,7 +25,7 @@ macro_rules! use_callback {
};
}
pub fn use_callback<T, R, F>(cx: &ScopeState, make: impl FnOnce() -> R) -> impl FnMut(T) + '_
pub fn use_callback<T, R, F>(, make: impl FnOnce() -> R) -> impl FnMut(T) + '_
where
R: FnMut(T) -> F + 'static,
F: Future<Output = ()> + 'static,
@@ -35,14 +35,14 @@ where
move |evt| cx.spawn(hook(evt))
}
fn _it_works(cx: &ScopeState) {
let _p = use_callback(cx, || {
fn _it_works() {
let _p = use_callback(|| {
|()| async {
//
}
});
// let p = use_callback!(cx, || |evt| async {
// let p = use_callback!(|| |evt| async {
// //
// });
}
+2 -2
View File
@@ -16,7 +16,7 @@ This is moderately efficient because the fields of the map are moved, but the da
However, if you used similar approach with Dioxus:
```rust
let (map, set_map) = use_state(cx, || HashMap::new());
let (map, set_map) = use_state(|| HashMap::new());
set_map({
let mut newmap = map.clone();
newmap.set(key, value);
@@ -37,7 +37,7 @@ uses the same memoization on top of the use_context API.
Here's a fully-functional todo app using the use_map API:
```rust
static TodoList: Component = |cx| {
let todos = use_map(cx, || HashMap::new());
let todos = use_map(|| HashMap::new());
let input = use_ref(|| None);
cx.render(rsx!{
+5 -6
View File
@@ -11,8 +11,8 @@ use dioxus_core::prelude::*;
/// ```rust, ignore
/// struct ComplexData(i32);
///
/// fn Component(cx: Scope) -> Element {
/// let id = use_const(cx, || ComplexData(100));
/// fn Component() -> Element {
/// let id = use_const(|| ComplexData(100));
///
/// cx.render(rsx! {
/// div { "{id.0}" }
@@ -20,8 +20,7 @@ use dioxus_core::prelude::*;
/// }
/// ```
#[must_use]
pub fn use_const<T: 'static>(
cx: &ScopeState,
pub fn use_const<T: 'static>
initial_state_fn: impl FnOnce() -> T,
) -> &UseConst<T> {
cx.use_hook(|| UseConst {
@@ -64,8 +63,8 @@ impl<T> std::ops::Deref for UseConst<T> {
fn use_const_makes_sense() {
#[allow(unused)]
fn app(cx: Scope) -> Element {
let const_val = use_const(cx, || vec![0, 1, 2, 3]);
fn app() -> Element {
let const_val = use_const(|| vec![0, 1, 2, 3]);
assert!(const_val[0] == 0);
+2 -2
View File
@@ -4,14 +4,14 @@ use dioxus_core::ScopeState;
///
/// Does not regenerate the value if the value is changed at the parent.
#[must_use]
pub fn use_context<T: 'static + Clone>(cx: &ScopeState) -> Option<&T> {
pub fn use_context<T: 'static + Clone>() -> Option<&T> {
cx.use_hook(|| cx.consume_context::<T>()).as_ref()
}
/// Provide some context via the tree and return a reference to it
///
/// Once the context has been provided, it is immutable. Mutations should be done via interior mutability.
pub fn use_context_provider<T: 'static + Clone>(cx: &ScopeState, f: impl FnOnce() -> T) -> &T {
pub fn use_context_provider<T: 'static + Clone>(f: impl FnOnce() -> T) -> &T {
cx.use_hook(|| {
let val = f();
cx.provide_context(val.clone());
+7 -7
View File
@@ -46,7 +46,7 @@ use std::future::Future;
/// Stop,
/// }
///
/// let chat_client = use_coroutine(cx, |mut rx: UnboundedReceiver<Action>| async move {
/// let chat_client = use_coroutine(|mut rx: UnboundedReceiver<Action>| async move {
/// while let Some(action) = rx.next().await {
/// match action {
/// Action::Start => {}
@@ -63,7 +63,7 @@ use std::future::Future;
/// }
/// })
/// ```
pub fn use_coroutine<M, G, F>(cx: &ScopeState, init: G) -> &Coroutine<M>
pub fn use_coroutine<M, G, F>(nit: G) -> &Coroutine<M>
where
M: 'static,
G: FnOnce(UnboundedReceiver<M>) -> F,
@@ -80,7 +80,7 @@ where
///
/// See the docs for [`use_coroutine`] for more details.
#[must_use]
pub fn use_coroutine_handle<M: 'static>(cx: &ScopeState) -> Option<&Coroutine<M>> {
pub fn use_coroutine_handle<M: 'static>() -> Option<&Coroutine<M>> {
cx.use_hook(|| cx.consume_context::<Coroutine<M>>())
.as_ref()
}
@@ -128,16 +128,16 @@ mod tests {
use futures_channel::mpsc::unbounded;
use futures_util::StreamExt;
fn app(cx: Scope, name: String) -> Element {
let task = use_coroutine(cx, |mut rx: UnboundedReceiver<i32>| async move {
fn app(name: String) -> Element {
let task = use_coroutine(|mut rx: UnboundedReceiver<i32>| async move {
while let Some(msg) = rx.next().await {
println!("got message: {msg}");
}
});
let task2 = use_coroutine(cx, view_task);
let task2 = use_coroutine(view_task);
let task3 = use_coroutine(cx, |rx| complex_task(rx, 10));
let task3 = use_coroutine(|rx| complex_task(rx, 10));
todo!()
}
+12 -12
View File
@@ -26,11 +26,11 @@ use crate::UseFutureDep;
/// ```rust, no_run
/// # use dioxus::prelude::*;
/// #[component]
/// fn Profile(cx: Scope, id: usize) -> Element {
/// let name = use_state(cx, || None);
/// fn Profile(id: usize) -> Element {
/// let name = use_state(|| None);
///
/// // Only fetch the user data when the id changes.
/// use_effect(cx, (id,), |(id,)| {
/// use_effect((id,), |(id,)| {
/// to_owned![name];
/// async move {
/// let user = fetch_user(id).await;
@@ -39,7 +39,7 @@ use crate::UseFutureDep;
/// });
///
/// // Only fetch the user data when the id changes.
/// use_effect(cx, (id,), |(id,)| {
/// use_effect((id,), |(id,)| {
/// to_owned![name];
/// async move {
/// let user = fetch_user(id).await;
@@ -56,11 +56,11 @@ use crate::UseFutureDep;
/// }
///
/// #[component]
/// fn App(cx: Scope) -> Element {
/// fn App() -> Element {
/// render!(Profile { id: 0 })
/// }
/// ```
pub fn use_effect<T, R, D>(cx: &ScopeState, dependencies: D, future: impl FnOnce(D::Out) -> R)
pub fn use_effect<T, R, D>(, dependencies: D, future: impl FnOnce(D::Out) -> R)
where
D: UseFutureDep,
R: UseEffectReturn<T>,
@@ -108,14 +108,14 @@ type UseEffectCleanup = Rc<RefCell<Option<Box<dyn FnOnce()>>>>;
/// Something that can be returned from a `use_effect` hook.
pub trait UseEffectReturn<T> {
fn apply(self, oncleanup: UseEffectCleanup, cx: &ScopeState) -> Task;
fn apply(self, oncleanup: UseEffectCleanup, ) -> Task;
}
impl<T> UseEffectReturn<()> for T
where
T: Future<Output = ()> + 'static,
{
fn apply(self, _: UseEffectCleanup, cx: &ScopeState) -> Task {
fn apply(self, _: UseEffectCleanup, ) -> Task {
cx.push_future(self)
}
}
@@ -127,7 +127,7 @@ where
T: Future<Output = F> + 'static,
F: FnOnce() + 'static,
{
fn apply(self, oncleanup: UseEffectCleanup, cx: &ScopeState) -> Task {
fn apply(self, oncleanup: UseEffectCleanup, ) -> Task {
cx.push_future(async move {
let cleanup = self.await;
*oncleanup.borrow_mut() = Some(Box::new(cleanup) as Box<dyn FnOnce()>);
@@ -154,17 +154,17 @@ mod tests {
fn app(cx: Scope<MyProps>) -> Element {
// should only ever run once
use_effect(cx, (), |_| async move {
use_effect((), |_| async move {
//
});
// runs when a is changed
use_effect(cx, (&cx.props.a,), |(a,)| async move {
use_effect((&cx.props.a,), |(a,)| async move {
//
});
// runs when a or b is changed
use_effect(cx, (&cx.props.a, &cx.props.b), |(a, b)| async move {
use_effect((&cx.props.a, &cx.props.b), |(a, b)| async move {
//
});
+8 -9
View File
@@ -17,8 +17,7 @@ use crate::{use_state, UseState};
/// will be canceled before the new one is started.
///
/// - dependencies: a tuple of references to values that are PartialEq + Clone
pub fn use_future<T, F, D>(
cx: &ScopeState,
pub fn use_future<T, F, D>
dependencies: D,
future: impl FnOnce(D::Out) -> F,
) -> &UseFuture<T>
@@ -27,7 +26,7 @@ where
F: Future<Output = T> + 'static,
D: UseFutureDep,
{
let val = use_state(cx, || None);
let val = use_state(|| None);
let state = cx.use_hook(move || UseFuture {
update: cx.schedule_update(),
@@ -95,7 +94,7 @@ impl<T> UseFuture<T> {
}
/// Forcefully cancel a future
pub fn cancel(&self, cx: &ScopeState) {
pub fn cancel(&self, ) {
if let Some(task) = self.task.take() {
cx.remove_future(task);
}
@@ -261,22 +260,22 @@ mod tests {
async fn app(cx: Scope<'_, MyProps>) -> Element {
// should only ever run once
let fut = use_future(cx, (), |_| async move {});
let fut = use_future((), |_| async move {});
// runs when a is changed
let fut = use_future(cx, (&cx.props.a,), |(a,)| async move {});
let fut = use_future((&cx.props.a,), |(a,)| async move {});
// runs when a or b is changed
let fut = use_future(cx, (&cx.props.a, &cx.props.b), |(a, b)| async move { 123 });
let fut = use_future((&cx.props.a, &cx.props.b), |(a, b)| async move { 123 });
let a = use_future!(cx, || async move {
let a = use_future!(|| async move {
// do the thing!
});
let b = &123;
let c = &123;
let a = use_future!(cx, |b, c| async move {
let a = use_future!(|b, c| async move {
let a = b + c;
let blah = "asd";
});
+4 -4
View File
@@ -13,8 +13,8 @@ use crate::UseFutureDep;
/// # use dioxus::prelude::*;
///
/// #[component]
/// fn Calculator(cx: Scope, number: usize) -> Element {
/// let bigger_number = use_memo(cx, (number,), |(number,)| {
/// fn Calculator(number: usize) -> Element {
/// let bigger_number = use_memo((number,), |(number,)| {
/// // This will only be calculated when `number` has changed.
/// number * 100
/// });
@@ -24,12 +24,12 @@ use crate::UseFutureDep;
/// }
///
/// #[component]
/// fn App(cx: Scope) -> Element {
/// fn App() -> Element {
/// render!(Calculator { number: 0 })
/// }
/// ```
#[must_use = "Consider using `use_effect` to run rerun a callback when dependencies change"]
pub fn use_memo<T, D>(cx: &ScopeState, dependencies: D, callback: impl FnOnce(D::Out) -> T) -> &T
pub fn use_memo<T, D>(, dependencies: D, callback: impl FnOnce(D::Out) -> T) -> &T
where
T: 'static,
D: UseFutureDep,
+1 -1
View File
@@ -7,7 +7,7 @@ use std::future::Future;
/// This is just [`use_effect`](crate::use_effect), but with no dependencies.
/// If you have no dependencies, it's recommended to use this, not just because it's more readable,
/// but also because it's a tiny bit more efficient.
pub fn use_on_create<T, F>(cx: &ScopeState, future: impl FnOnce() -> F)
pub fn use_on_create<T, F>(future: impl FnOnce() -> F)
where
T: 'static,
F: Future<Output = T> + 'static,
+7 -7
View File
@@ -4,7 +4,7 @@ This is deprecated because of the introduction of `use_on_create` which is bette
The reason why `use_on_create` is not `use_on_mount` is because of potential confusion with `dioxus::events::onmounted`."
)]
pub fn use_on_unmount<D: FnOnce() + 'static>(cx: &dioxus_core::ScopeState, destroy: D) {
use_on_destroy(cx, destroy);
use_on_destroy(destroy);
}
/// Creates a callback that will be run before the component is removed.
@@ -15,8 +15,8 @@ pub fn use_on_unmount<D: FnOnce() + 'static>(cx: &dioxus_core::ScopeState, destr
/// ```rust
/// use dioxus::prelude::*;
///
/// fn app(cx: Scope) -> Element {
/// let state = use_state(cx, || true);
/// fn app() -> Element {
/// let state = use_state(|| true);
/// render! {
/// for _ in 0..100 {
/// h1 {
@@ -37,9 +37,9 @@ pub fn use_on_unmount<D: FnOnce() + 'static>(cx: &dioxus_core::ScopeState, destr
/// }
/// }
///
/// fn child_component(cx: Scope) -> Element {
/// let original_scroll_position = use_state(cx, || 0.0);
/// use_effect(cx, (), move |_| {
/// fn child_component() -> Element {
/// let original_scroll_position = use_state(|| 0.0);
/// use_effect((), move |_| {
/// to_owned![original_scroll_position];
/// async move {
/// let window = web_sys::window().unwrap();
@@ -50,7 +50,7 @@ pub fn use_on_unmount<D: FnOnce() + 'static>(cx: &dioxus_core::ScopeState, destr
/// }
/// });
///
/// use_on_destroy(cx, {
/// use_on_destroy({
/// to_owned![original_scroll_position];
/// /// restore scroll to the top of the page
/// move || {
+1 -1
View File
@@ -111,7 +111,7 @@ use std::{
/// })
/// ```
#[must_use]
pub fn use_ref<T: 'static>(cx: &ScopeState, initialize_refcell: impl FnOnce() -> T) -> &UseRef<T> {
pub fn use_ref<T: 'static>(nitialize_refcell: impl FnOnce() -> T) -> &UseRef<T> {
let hook = cx.use_hook(|| UseRef {
update: cx.schedule_update(),
value: Rc::new(RefCell::new(initialize_refcell())),
+1 -1
View File
@@ -1,7 +1,7 @@
use dioxus_core::ScopeState;
///
pub fn use_root_context<T: 'static + Clone>(cx: &ScopeState, new: impl FnOnce() -> T) -> &T {
pub fn use_root_context<T: 'static + Clone>(, new: impl FnOnce() -> T) -> &T {
cx.use_hook(|| {
cx.consume_context::<T>()
.unwrap_or_else(|| cx.provide_root_context(new()))
+13 -13
View File
@@ -1,5 +1,5 @@
use self::error::{UseSharedStateError, UseSharedStateResult};
use dioxus_core::{ScopeId, ScopeState};
use dioxus_core::ScopeId;
use std::{collections::HashSet, rc::Rc, sync::Arc};
#[cfg(debug_assertions)]
@@ -104,7 +104,7 @@ impl<T> ProvidedStateInner<T> {
/// ```rust
/// # use dioxus::prelude::*;
/// #
/// # fn app(cx: Scope) -> Element {
/// # fn app() -> Element {
/// # render! {
/// # Parent{}
/// # }
@@ -117,9 +117,9 @@ impl<T> ProvidedStateInner<T> {
/// }
///
/// // Provider
/// fn Parent<'a>(cx: Scope<'a>) -> Element<'a> {
/// use_shared_state_provider(cx, || Theme::Dark);
/// let theme = use_shared_state::<Theme>(cx).unwrap();
/// fn Parent<'a>(cx: Scope<'a>) -> Element {
/// use_shared_state_provider(|| Theme::Dark);
/// let theme = use_shared_state::<Theme>().unwrap();
///
/// render! {
/// button{
@@ -137,8 +137,8 @@ impl<T> ProvidedStateInner<T> {
/// }
///
/// // Consumer
/// fn Child<'a>(cx: Scope<'a>) -> Element<'a> {
/// let theme = use_shared_state::<Theme>(cx).unwrap();
/// fn Child<'a>(cx: Scope<'a>) -> Element {
/// let theme = use_shared_state::<Theme>().unwrap();
/// let current_theme = *theme.read();
///
/// render! {
@@ -160,7 +160,7 @@ impl<T> ProvidedStateInner<T> {
///
/// Right now, there is not a distinction between read-only and write-only, so every consumer will be notified.
#[must_use]
pub fn use_shared_state<T: 'static>(cx: &ScopeState) -> Option<&UseSharedState<T>> {
pub fn use_shared_state<T: 'static>() -> Option<&UseSharedState<T>> {
let state_owner: &mut Option<UseSharedStateOwner<T>> = &mut *cx.use_hook(move || {
let scope_id = cx.scope_id();
let root = cx.consume_context::<ProvidedState<T>>()?;
@@ -330,7 +330,7 @@ impl<T> PartialEq for UseSharedState<T> {
/// ```rust
/// # use dioxus::prelude::*;
/// #
/// # fn app(cx: Scope) -> Element {
/// # fn app() -> Element {
/// # render! {
/// # Parent{}
/// # }
@@ -343,9 +343,9 @@ impl<T> PartialEq for UseSharedState<T> {
/// }
///
/// // Provider
/// fn Parent<'a>(cx: Scope<'a>) -> Element<'a> {
/// use_shared_state_provider(cx, || Theme::Dark);
/// let theme = use_shared_state::<Theme>(cx).unwrap();
/// fn Parent<'a>(cx: Scope<'a>) -> Element {
/// use_shared_state_provider(|| Theme::Dark);
/// let theme = use_shared_state::<Theme>().unwrap();
///
/// render! {
/// button{
@@ -362,7 +362,7 @@ impl<T> PartialEq for UseSharedState<T> {
/// }
/// }
/// ```
pub fn use_shared_state_provider<T: 'static>(cx: &ScopeState, f: impl FnOnce() -> T) {
pub fn use_shared_state_provider<T: 'static>(f: impl FnOnce() -> T) {
cx.use_hook(|| {
let state: ProvidedState<T> = Rc::new(RefCell::new(ProvidedStateInner {
value: f(),
+16 -17
View File
@@ -19,7 +19,7 @@ use std::{
///
/// ```ignore
/// const Example: Component = |cx| {
/// let count = use_state(cx, || 0);
/// let count = use_state(|| 0);
///
/// cx.render(rsx! {
/// div {
@@ -31,8 +31,7 @@ use std::{
/// }
/// ```
#[must_use]
pub fn use_state<T: 'static>(
cx: &ScopeState,
pub fn use_state<T: 'static>
initial_state_fn: impl FnOnce() -> T,
) -> &UseState<T> {
let hook = cx.use_hook(move || {
@@ -92,8 +91,8 @@ impl<T: 'static> UseState<T> {
/// An async context might need to know the current value:
///
/// ```rust, ignore
/// fn component(cx: Scope) -> Element {
/// let count = use_state(cx, || 0);
/// fn component() -> Element {
/// let count = use_state(|| 0);
/// cx.spawn({
/// let set_count = count.to_owned();
/// async move {
@@ -119,8 +118,8 @@ impl<T: 'static> UseState<T> {
/// A component might require an `Rc<dyn Fn(T)>` as an input to set a value.
///
/// ```rust, ignore
/// fn component(cx: Scope) -> Element {
/// let value = use_state(cx, || 0);
/// fn component() -> Element {
/// let value = use_state(|| 0);
///
/// rsx!{
/// Component {
@@ -144,8 +143,8 @@ impl<T: 'static> UseState<T> {
/// ```rust, ignore
/// # use dioxus_core::prelude::*;
/// # use dioxus_hooks::*;
/// fn component(cx: Scope) -> Element {
/// let value = use_state(cx, || 0);
/// fn component() -> Element {
/// let value = use_state(|| 0);
///
/// // to increment the value
/// value.modify(|v| v + 1);
@@ -185,8 +184,8 @@ impl<T: 'static> UseState<T> {
/// ```rust, ignore
/// # use dioxus_core::prelude::*;
/// # use dioxus_hooks::*;
/// fn component(cx: Scope) -> Element {
/// let value = use_state(cx, || 0);
/// fn component() -> Element {
/// let value = use_state(|| 0);
///
/// let as_rc = value.get();
/// assert_eq!(as_rc.as_ref(), &0);
@@ -207,8 +206,8 @@ impl<T: 'static> UseState<T> {
/// Mark the component that create this [`UseState`] as dirty, forcing it to re-render.
///
/// ```rust, ignore
/// fn component(cx: Scope) -> Element {
/// let count = use_state(cx, || 0);
/// fn component() -> Element {
/// let count = use_state(|| 0);
/// cx.spawn({
/// let count = count.to_owned();
/// async move {
@@ -238,7 +237,7 @@ impl<T: Clone> UseState<T> {
/// # Examples
///
/// ```rust, ignore
/// let val = use_state(cx, || 0);
/// let val = use_state(|| 0);
///
/// val.with_mut(|v| *v = 1);
/// ```
@@ -270,7 +269,7 @@ impl<T: Clone> UseState<T> {
/// # Examples
///
/// ```rust, ignore
/// let val = use_state(cx, || 0);
/// let val = use_state(|| 0);
///
/// *val.make_mut() += 1;
/// ```
@@ -493,8 +492,8 @@ impl<T: Div<Output = T> + Copy> std::ops::DivAssign<T> for UseState<T> {
#[test]
fn api_makes_sense() {
#[allow(unused)]
fn app(cx: Scope) -> Element {
let val = use_state(cx, || 0);
fn app() -> Element {
let val = use_state(|| 0);
val.set(0);
val.modify(|v| v + 1);
+2 -2
View File
@@ -1,8 +1,8 @@
use axum::{extract::ws::WebSocketUpgrade, response::Html, routing::get, Router};
use dioxus::prelude::*;
fn app(cx: Scope) -> Element {
let mut num = use_state(cx, || 0);
fn app() -> Element {
let mut num = use_state(|| 0);
cx.render(rsx! {
div {
+3 -3
View File
@@ -1,9 +1,9 @@
use axum::{extract::ws::WebSocketUpgrade, response::Html, routing::get, Router};
use dioxus::prelude::*;
fn app(cx: Scope) -> Element {
let state = use_state(cx, || 0);
use_future(cx, (), |_| {
fn app() -> Element {
let state = use_state(|| 0);
use_future((), |_| {
to_owned![state];
async move {
loop {
+2 -2
View File
@@ -7,8 +7,8 @@ use rocket::response::content::RawHtml;
use rocket::{Config, Rocket, State};
use rocket_ws::{Channel, WebSocket};
fn app(cx: Scope) -> Element {
let mut num = use_state(cx, || 0);
fn app() -> Element {
let mut num = use_state(|| 0);
cx.render(rsx! {
div {
+2 -2
View File
@@ -5,8 +5,8 @@ use salvo::prelude::*;
use std::net::SocketAddr;
use std::sync::Arc;
fn app(cx: Scope) -> Element {
let mut num = use_state(cx, || 0);
fn app() -> Element {
let mut num = use_state(|| 0);
cx.render(rsx! {
div {
+2 -2
View File
@@ -5,8 +5,8 @@ use std::net::SocketAddr;
use warp::ws::Ws;
use warp::Filter;
fn app(cx: Scope) -> Element {
let mut num = use_state(cx, || 0);
fn app() -> Element {
let mut num = use_state(|| 0);
cx.render(rsx! {
div {
+1 -2
View File
@@ -1,14 +1,13 @@
#![allow(clippy::await_holding_refcell_ref)]
use async_trait::async_trait;
use dioxus_core::ScopeState;
use dioxus_html::prelude::{EvalError, EvalProvider, Evaluator};
use std::{cell::RefCell, rc::Rc};
use crate::query::{Query, QueryEngine};
/// Provides the DesktopEvalProvider through [`cx.provide_context`].
pub fn init_eval(cx: &ScopeState) {
pub fn init_eval() {
let query = cx.consume_context::<QueryEngine>().unwrap();
let provider: Rc<dyn EvalProvider> = Rc::new(DesktopEvalProvider { query });
cx.provide_context(provider);
+1 -1
View File
@@ -257,7 +257,7 @@ fn text_frame(text: &str) -> Vec<u8> {
}
fn add_template(
template: &Template<'static>,
template: &Template,
channel: &mut Channel,
templates: &mut FxHashMap<String, u16>,
max_template_count: &mut u16,
+1 -1
View File
@@ -79,7 +79,7 @@ fn main() {
dioxus_mobile::launch(app);
}
fn app(cx: Scope) -> Element {
fn app() -> Element {
cx.render(rsx!{
div {
"hello world!"
@@ -166,10 +166,10 @@ impl State for Border {
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
fn app(cx: Scope) -> Element {
let count = use_state(cx, || 0);
fn app() -> Element {
let count = use_state(|| 0);
use_future(cx, (count,), |(count,)| async move {
use_future((count,), |(count,)| async move {
loop {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
count.set(*count + 1);
@@ -185,7 +185,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
})
}
fn Comp(cx: Scope) -> Element {
fn Comp() -> Element {
cx.render(rsx! {
div{
border: "",
@@ -201,7 +201,7 @@ fn traverse() {
use crate::prelude::*;
use dioxus::prelude::*;
#[allow(non_snake_case)]
fn Base(cx: Scope) -> Element {
fn Base() -> Element {
render!(
div{
div{
@@ -299,7 +299,7 @@ fn persist_removes() {
use crate::prelude::*;
use dioxus::prelude::*;
#[allow(non_snake_case)]
fn Base(cx: Scope) -> Element {
fn Base() -> Element {
let children = match generation() % 2 {
0 => 3,
1 => 2,
@@ -375,7 +375,7 @@ fn persist_instertions_before() {
use crate::prelude::*;
use dioxus::prelude::*;
#[allow(non_snake_case)]
fn Base(cx: Scope) -> Element {
fn Base() -> Element {
let children = match generation() % 2 {
0 => 3,
1 => 2,
@@ -428,7 +428,7 @@ fn persist_instertions_after() {
use crate::prelude::*;
use dioxus::prelude::*;
#[allow(non_snake_case)]
fn Base(cx: Scope) -> Element {
fn Base() -> Element {
let children = match generation() % 2 {
0 => 3,
1 => 2,
@@ -115,7 +115,7 @@ macro_rules! test_state{
#[test]
fn state_reduce_initally_called_minimally() {
#[allow(non_snake_case)]
fn Base(cx: Scope) -> Element {
fn Base() -> Element {
render!{
div {
div{
+5 -5
View File
@@ -256,10 +256,10 @@ impl CustomElement for CustomElementWithNoSlot {
#[test]
fn custom_elements_work() {
fn app(cx: Scope) -> Element {
let count = use_state(cx, || 0);
fn app() -> Element {
let count = use_state(|| 0);
use_future!(cx, |count| async move {
use_future!(|count| async move {
count.with_mut(|count| *count += 1);
});
@@ -333,7 +333,7 @@ fn custom_elements_work() {
#[test]
#[should_panic]
fn slotless_custom_element_cant_have_children() {
fn app(cx: Scope) -> Element {
fn app() -> Element {
cx.render(rsx! {
customelementnoslot {
testing132 {}
@@ -362,7 +362,7 @@ fn slotless_custom_element_cant_have_children() {
#[test]
fn slotless_custom_element() {
fn app(cx: Scope) -> Element {
fn app() -> Element {
cx.render(rsx! {
customelementnoslot {
}
+4 -4
View File
@@ -134,7 +134,7 @@ enum DynamicNodeType {
Other,
}
fn create_random_template(name: &'static str) -> (Template<'static>, Vec<DynamicNodeType>) {
fn create_random_template(name: &'static str) -> (Template, Vec<DynamicNodeType>) {
let mut dynamic_node_type = Vec::new();
let mut template_idx = 0;
let mut attr_idx = 0;
@@ -175,7 +175,7 @@ fn create_random_template(name: &'static str) -> (Template<'static>, Vec<Dynamic
)
}
fn create_random_dynamic_node(cx: &ScopeState, depth: usize) -> DynamicNode {
fn create_random_dynamic_node(, depth: usize) -> DynamicNode {
let range = if depth > 3 { 1 } else { 3 };
match rand::random::<u8>() % range {
0 => DynamicNode::Placeholder(Default::default()),
@@ -207,7 +207,7 @@ fn create_random_dynamic_node(cx: &ScopeState, depth: usize) -> DynamicNode {
}
}
fn create_random_dynamic_attr(cx: &ScopeState) -> Attribute {
fn create_random_dynamic_attr() -> Attribute {
let value = match rand::random::<u8>() % 6 {
0 => AttributeValue::Text(Box::leak(
format!("{}", rand::random::<usize>()).into_boxed_str(),
@@ -269,7 +269,7 @@ fn create_random_element(cx: Scope<DepthProps>) -> Element {
format!("{}", rand::random::<usize>()).into_boxed_str(),
))),
DynamicNodeType::Other => {
create_random_dynamic_node(cx, cx.props.depth + 1)
create_random_dynamic_node(cx.props.depth + 1)
}
})
.collect();
+5 -5
View File
@@ -96,16 +96,16 @@ fn native_core_is_okay() {
use std::sync::{Arc, Mutex};
use std::time::Duration;
fn app(cx: Scope) -> Element {
let colors = use_state(cx, || vec!["green", "blue", "red"]);
let padding = use_state(cx, || 10);
fn app() -> Element {
let colors = use_state(|| vec!["green", "blue", "red"]);
let padding = use_state(|| 10);
use_effect(cx, colors, |colors| async move {
use_effect(colors, |colors| async move {
sleep(Duration::from_millis(1000)).await;
colors.with_mut(|colors| colors.reverse());
});
use_effect(cx, padding, |padding| async move {
use_effect(padding, |padding| async move {
sleep(Duration::from_millis(10)).await;
padding.with_mut(|padding| {
if *padding < 65 {
Loaded 100 of 226 files, more files were not shown because too many files have changed in this diff. Show more