(),
+ |cx, res| match res {
Ok(res) => rsx!(in cx, img { src: "{res.message}" }),
Err(_) => rsx!(in cx, div { "No doggos for you :(" }),
- }
- });
+ },
+ );
cx.render(rsx!(
div {
@@ -30,34 +30,3 @@ pub static App: FC<()> = |cx| {
}
))
};
-
-// use dioxus_core::virtual_dom::SuspendedContext;
-use futures::Future;
-use futures::FutureExt;
-use std::pin::Pin;
-
-fn use_fetch<'a, T, P, F>(cx: Context, url: &str, g: F) -> VNode<'a>
-where
- T: serde::de::DeserializeOwned + 'static,
- // F: FnOnce(SuspendedContext, surf::Result) -> VNode<'a> + 'a,
- F: FnOnce((), surf::Result) -> VNode<'a> + 'a,
-{
- todo!()
- // // essentially we're doing a "use_effect" but with no dependent props or post-render shenanigans
- // let fetch_promise = cx.use_hook(
- // move || surf::get(url).recv_json::().boxed_local(),
- // // just pass the future through
- // |p| p,
- // |_| (),
- // );
- // cx.suspend(fetch_promise, g)
-}
-
-/// Spawns the future only when the inputs change
-fn use_future_effect<'a, 'b, F, P, F2>(cx: Context, g: F2) -> VNode<'a>
-where
- F: Future>,
- F2: FnOnce() -> F + 'a,
-{
- todo!()
-}
diff --git a/examples/reference/task.rs b/examples/reference/task.rs
new file mode 100644
index 000000000..ac1fc3686
--- /dev/null
+++ b/examples/reference/task.rs
@@ -0,0 +1,61 @@
+//! Example: Tasks
+//! --------------
+//!
+//! Built around the same system that powers suspense, Dioxus also allows users to write arbitrary tasks that can modify
+//! state asynchronously. `use_task` takes a future and returns a task handle and an option that holds the tasks's return
+//! value. When the task completes, the component will re-render with the result freshly available.
+//!
+//! Tasks don't necessarily need to complete, however. It would be completely reasonable to wire up a websocket receiver
+//! in a task and have it work infinitely while the app is running. If the socket throws an error, the task could complete
+//! and the UI could present a helpful error message.
+//!
+//! Tasks also return the `TaskHandle` type which lets other component logic start, stop, and restart the task at any time.
+//! Tasks are very much like an async-flavoroued coroutine, making them incredibly powerful.
+//!
+//! Tasks must be valid for the 'static lifetime, so any state management neeeds to be cloned into the closure. `use_state`
+//! has a method called `for_async` which generates an AsyncUseState wrapper. This has a very similar API to the regualr
+//! `use_state` but is `static.
+//!
+//! Remeber `use_task` is a hook! Don't call it out of order or in loops. You might aaccidentally swap the task handles
+//! and break things in subtle ways.
+//!
+//! Whenever a component is scheduled for deletion, the task is dropped. Make sure that whatever primitives used in the
+//! task have a valid drop implementation and won't leave resources tied up.
+
+use dioxus::prelude::*;
+
+pub static Example: FC<()> = |cx| {
+ let count = use_state(cx, || 0);
+ let mut direction = use_state(cx, || 1);
+
+ // Tasks are 'static, so we need to copy relevant items in
+ let (async_count, dir) = (count.for_async(), *direction);
+ let (task, result) = cx.use_task(move || async move {
+ // Count infinitely!
+ loop {
+ gloo_timers::future::TimeoutFuture::new(250).await;
+ *async_count.get_mut() += dir;
+ }
+ });
+
+ cx.render(rsx! {
+ div {
+ h1 {"count is {count}"}
+ button {
+ "Stop counting"
+ onclick: move |_| task.stop()
+ }
+ button {
+ "Start counting"
+ onclick: move |_| task.start()
+ }
+ button {
+ "Switch counting direcion"
+ onclick: move |_| {
+ direction *= -1;
+ task.restart();
+ }
+ }
+ }
+ })
+};
diff --git a/examples/reference/testing.rs b/examples/reference/testing.rs
index 096f0d9e0..d59e9619a 100644
--- a/examples/reference/testing.rs
+++ b/examples/reference/testing.rs
@@ -1,7 +1,6 @@
use dioxus::prelude::*;
-fn main() {}
-static Example: FC<()> = |cx| {
+pub static Example: FC<()> = |cx| {
cx.render(rsx! {
div {
diff --git a/examples/reference/tostring.rs b/examples/reference/tostring.rs
index 096f0d9e0..c28c1ef4f 100644
--- a/examples/reference/tostring.rs
+++ b/examples/reference/tostring.rs
@@ -1,10 +1,25 @@
use dioxus::prelude::*;
-fn main() {}
+use dioxus::ssr;
+
+pub static Example: FC<()> = |cx| {
+ let as_string = use_state(cx, || {
+ // Currently, SSR is only supported for whole VirtualDOMs
+ // This is an easy/low hanging fruit to improve upon
+ let mut dom = VirtualDom::new(SomeApp);
+ dom.rebuild_in_place().unwrap();
+ ssr::render_root(&dom)
+ });
-static Example: FC<()> = |cx| {
cx.render(rsx! {
- div {
+ div { "{as_string}" }
+ })
+};
+static SomeApp: FC<()> = |cx| {
+ cx.render(rsx! {
+ div { style: {background_color: "blue"}
+ h1 {"Some amazing app or component"}
+ p {"Things are great"}
}
})
};
diff --git a/examples/reference/webcomponents.rs b/examples/reference/webcomponents.rs
deleted file mode 100644
index e141d6cd7..000000000
--- a/examples/reference/webcomponents.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-//! Example: Web Components
-//! -----------------------
-//!
-//! Web components are a flavor of html elements that can be user-defined.
-//! See: https://www.webcomponents.org for more information.
-//!
-//! Users who use webcomponents typically don't use Dioxus. However, if you would like to use webcomponents in Dioxus,
-//! you can easily create a new custom element with compile-time correct wrappers around the webcomponent.
-//!
-//! We don't support building new webcomponents with Dioxus, however.
-//!
-
-fn main() {}
-
-mod dioxus_elements {
- use dioxus::prelude::DioxusElement;
-
- struct custom_element;
- impl DioxusElement for custom_element {
- const TAG_NAME: &'static str = "custom_element";
- const NAME_SPACE: Option<&'static str> = None;
- }
-
- // Re-export the normal html namespace
- pub use dioxus::prelude::dioxus_elements::*;
-}
diff --git a/examples/rsx_usage.rs b/examples/rsx_usage.rs
index ba5ec951e..7e4399800 100644
--- a/examples/rsx_usage.rs
+++ b/examples/rsx_usage.rs
@@ -49,7 +49,7 @@ const NONE_ELEMENT: Option<()> = None;
use baller::Baller;
use dioxus::prelude::*;
-static Example: FC<()> = |cx| {
+pub static Example: FC<()> = |cx| {
let formatting = "formatting!";
let formatting_tuple = ("a", "b");
let lazy_fmt = format_args!("lazily formatted text");
diff --git a/examples/tailwind.rs b/examples/tailwind.rs
index 9b6a186bd..1c71caa7f 100644
--- a/examples/tailwind.rs
+++ b/examples/tailwind.rs
@@ -12,7 +12,7 @@ fn main() {
const STYLE: &str = "body {overflow:hidden;}";
-pub const App: FC<()> = |cx| {
+pub static App: FC<()> = |cx| {
cx.render(rsx!(
div { class: "overflow-hidden"
style { "{STYLE}" }
@@ -28,7 +28,7 @@ pub const App: FC<()> = |cx| {
))
};
-pub const Header: FC<()> = |cx| {
+pub static Header: FC<()> = |cx| {
cx.render(rsx! {
div {
header { class: "text-gray-400 bg-gray-900 body-font"
@@ -54,7 +54,7 @@ pub const Header: FC<()> = |cx| {
})
};
-pub const Hero: FC<()> = |cx| {
+pub static Hero: FC<()> = |cx| {
//
cx.render(rsx! {
section{ class: "text-gray-400 bg-gray-900 body-font"
@@ -92,7 +92,7 @@ pub const Hero: FC<()> = |cx| {
}
})
};
-pub const Entry: FC<()> = |cx| {
+pub static Entry: FC<()> = |cx| {
//
cx.render(rsx! {
section{ class: "text-gray-400 bg-gray-900 body-font"
@@ -105,7 +105,7 @@ pub const Entry: FC<()> = |cx| {
})
};
-pub const StacksIcon: FC<()> = |cx| {
+pub static StacksIcon: FC<()> = |cx| {
cx.render(rsx!(
svg {
// xmlns: "http://www.w3.org/2000/svg"
@@ -120,7 +120,7 @@ pub const StacksIcon: FC<()> = |cx| {
}
))
};
-pub const RightArrowIcon: FC<()> = |cx| {
+pub static RightArrowIcon: FC<()> = |cx| {
cx.render(rsx!(
svg {
fill: "none"
diff --git a/examples/todomvc.rs b/examples/todomvc.rs
new file mode 100644
index 000000000..b4a4a2fd8
--- /dev/null
+++ b/examples/todomvc.rs
@@ -0,0 +1,114 @@
+use dioxus::prelude::*;
+use im_rc::HashMap;
+use std::rc::Rc;
+
+fn main() {
+ #[cfg(feature = "desktop")]
+ // #[cfg(not(target_arch = "wasm32"))]
+ dioxus::desktop::launch(App, |c| c);
+
+ #[cfg(feature = "desktop")]
+ dioxus::web::launch(App, |c| c);
+}
+
+#[derive(PartialEq)]
+pub enum FilterState {
+ All,
+ Active,
+ Completed,
+}
+
+#[derive(Debug, PartialEq)]
+pub struct TodoItem {
+ pub id: u32,
+ pub checked: bool,
+ pub contents: String,
+}
+
+const STYLE: &str = include_str!("./_examples/todomvc/style.css");
+const App: FC<()> = |cx| {
+ let draft = use_state(cx, || "".to_string());
+ let todos = use_state(cx, || HashMap::>::new());
+ let filter = use_state(cx, || FilterState::All);
+
+ let todolist = todos
+ .iter()
+ .filter(|(id, item)| match *filter {
+ FilterState::All => true,
+ FilterState::Active => !item.checked,
+ FilterState::Completed => item.checked,
+ })
+ .map(|(id, todo)| {
+ rsx!(TodoEntry {
+ key: "{id}",
+ todo: todo.clone()
+ })
+ })
+ .collect::>();
+
+ let items_left = todolist.len();
+ let item_text = match items_left {
+ 1 => "item",
+ _ => "items",
+ };
+
+ cx.render(rsx! {
+ div { id: "app"
+ style {"{STYLE}"}
+ div {
+ header { class: "header"
+ h1 {"todos"}
+ input {
+ class: "new-todo"
+ placeholder: "What needs to be done?"
+ value: "{draft}"
+ oninput: move |evt| draft.set(evt.value())
+ }
+ }
+ {todolist}
+ {(!todos.is_empty()).then(|| rsx!(
+ footer {
+ span { strong {"{items_left}"} span {"{item_text} left"} }
+ ul { class: "filters"
+ li { class: "All", a { href: "", onclick: move |_| filter.set(FilterState::All), "All" }}
+ li { class: "Active", a { href: "active", onclick: move |_| filter.set(FilterState::Active), "Active" }}
+ li { class: "Completed", a { href: "completed", onclick: move |_| filter.set(FilterState::Completed), "Completed" }}
+ }
+ }
+ ))}
+ }
+ footer { class: "info"
+ p {"Double-click to edit a todo"}
+ p { "Created by ", a { "jkelleyrtp", href: "http://github.com/jkelleyrtp/" }}
+ p { "Part of ", a { "TodoMVC", href: "http://todomvc.com" }}
+ }
+ }
+ })
+};
+
+#[derive(PartialEq, Props)]
+pub struct TodoEntryProps {
+ todo: std::rc::Rc,
+}
+
+pub fn TodoEntry(cx: Context) -> VNode {
+ let TodoEntryProps { todo } = *cx;
+ let is_editing = use_state(cx, || false);
+ let contents = "";
+
+ cx.render(rsx! (
+ li {
+ "{todo.id}"
+ input {
+ class: "toggle"
+ r#type: "checkbox"
+ "{todo.checked}"
+ }
+ {is_editing.then(|| rsx!{
+ input {
+ value: "{contents}"
+ }
+ })}
+ }
+ ))
+}
diff --git a/notes/Parity.md b/notes/Parity.md
index 76b1cf992..11655c2e7 100644
--- a/notes/Parity.md
+++ b/notes/Parity.md
@@ -12,7 +12,7 @@ https://github.com/rustwasm/gloo
For example, resize observer would function like this:
```rust
-static Example: FC<()> = |cx| {
+pub static Example: FC<()> = |cx| {
let observer = use_resize_observer();
cx.render(rsx!(
@@ -29,18 +29,18 @@ For other services, we shell out to gloo. If the gloo service doesn't exist, the
| Service | Hook examples | Current Projects |
| ---------------------------- | ------------- | ---------------- |
-| Fetch | 👀 | Reqwest/surf |
-| Local storage (cache) | 👀 | Gloo |
-| Persistent storage (IndexDB) | 👀 | 👀 |
-| WebSocket | 👀 | Gloo |
-| 3D Renderer / WebGL | 👀 | Gloo |
-| Web Worker | 👀 | 👀 |
-| Router | 👀 | 👀 |
-| Notifications | 👀 | 👀 |
-| WebRTC Client | 👀 | 👀 |
-| Service Workers | 👀 | 👀 |
-| Resize Observer | 👀 | 👀 |
-| Canvas | 👀 | 👀 |
-| Clipboard | 👀 | 👀 |
-| Fullscreen | 👀 | 👀 |
-| History API | 👀 | 👀 |
+| Fetch | 👀 | Reqwest/surf |
+| Local storage (cache) | 👀 | Gloo |
+| Persistent storage (IndexDB) | 👀 | 👀 |
+| WebSocket | 👀 | Gloo |
+| 3D Renderer / WebGL | 👀 | Gloo |
+| Web Worker | 👀 | 👀 |
+| Router | 👀 | 👀 |
+| Notifications | 👀 | 👀 |
+| WebRTC Client | 👀 | 👀 |
+| Service Workers | 👀 | 👀 |
+| Resize Observer | 👀 | 👀 |
+| Canvas | 👀 | 👀 |
+| Clipboard | 👀 | 👀 |
+| Fullscreen | 👀 | 👀 |
+| History API | 👀 | 👀 |
diff --git a/notes/SOLVEDPROBLEMS.md b/notes/SOLVEDPROBLEMS.md
index 25febf0c4..ba2a168d1 100644
--- a/notes/SOLVEDPROBLEMS.md
+++ b/notes/SOLVEDPROBLEMS.md
@@ -153,13 +153,13 @@ Notice that LiveComponent receivers (the client-side interpretation of a LiveCom
The `VNodeTree` type is a very special type that allows VNodes to be created using a pluggable allocator. The html! macro creates something that looks like:
```rust
-static Example: FC<()> = |cx| {
+pub static Example: FC<()> = |cx| {
html! { "blah"
}
};
// expands to...
-static Example: FC<()> = |cx| {
+pub static Example: FC<()> = |cx| {
// This function converts a Fn(allocator) -> VNode closure to a VNode struct that will later be evaluated.
html_macro_to_vnodetree(move |allocator| {
let mut node0 = allocator.alloc(VElement::div);
diff --git a/packages/core-macro/src/rsx/ambiguous.rs b/packages/core-macro/src/rsx/ambiguous.rs
index 002c27bb9..7b894c6e2 100644
--- a/packages/core-macro/src/rsx/ambiguous.rs
+++ b/packages/core-macro/src/rsx/ambiguous.rs
@@ -39,32 +39,18 @@ impl Parse for AmbiguousElement {
}
}
- // if input.peek(Ident) {
- // let name_str = input.fork().parse::().unwrap().to_string();
- // } else {
- // }
-
if let Ok(name) = input.fork().parse::() {
let name_str = name.to_string();
- match is_valid_tag(&name_str) {
- true => input
+ let first_char = name_str.chars().next().unwrap();
+ if first_char.is_ascii_uppercase() {
+ input
+ .parse::()
+ .map(|c| AmbiguousElement::Component(c))
+ } else {
+ input
.parse::()
- .map(|c| AmbiguousElement::Element(c)),
- false => {
- let first_char = name_str.chars().next().unwrap();
- if first_char.is_ascii_uppercase() {
- input
- .parse::()
- .map(|c| AmbiguousElement::Component(c))
- } else {
- let name = input.parse::().unwrap();
- Err(Error::new(
- name.span(),
- "Components must be uppercased, perhaps you mispelled a html tag",
- ))
- }
- }
+ .map(|c| AmbiguousElement::Element(c))
}
} else {
if input.peek(LitStr) {
diff --git a/packages/core-macro/src/rsx/component.rs b/packages/core-macro/src/rsx/component.rs
index 99c1e1a40..c3a5c143b 100644
--- a/packages/core-macro/src/rsx/component.rs
+++ b/packages/core-macro/src/rsx/component.rs
@@ -96,7 +96,7 @@ pub fn parse_component_body(
}
content.parse::()?;
*manual_props = Some(content.parse::()?);
- } else if content.peek(Ident) && content.peek2(Token![:]) {
+ } else if content.peek(Ident) && content.peek2(Token![:]) && !content.peek3(Token![:]) {
if !cfg.allow_fields {
return Err(Error::new(
content.span(),
@@ -184,7 +184,7 @@ impl ToTokens for Component {
};
tokens.append_all(quote! {
- __cx.virtual_child(
+ __cx.component(
#name,
#builder,
#key_token,
diff --git a/packages/core-macro/src/rsx/element.rs b/packages/core-macro/src/rsx/element.rs
index 5a17ec635..41d39fe9d 100644
--- a/packages/core-macro/src/rsx/element.rs
+++ b/packages/core-macro/src/rsx/element.rs
@@ -43,11 +43,6 @@ impl Parse for Element {
fn parse(stream: ParseStream) -> Result {
let name = Ident::parse(stream)?;
- // TODO: remove this in favor of the compile-time validation system
- if !crate::util::is_valid_tag(&name.to_string()) {
- return Err(Error::new(name.span(), "Not a valid Html tag"));
- }
-
// parse the guts
let content: ParseBuffer;
syn::braced!(content in stream);
diff --git a/packages/core/examples/alternative.rs b/packages/core/examples/alternative.rs
index b12a8f69c..cfe98b9bc 100644
--- a/packages/core/examples/alternative.rs
+++ b/packages/core/examples/alternative.rs
@@ -4,7 +4,7 @@ fn main() {}
// use dioxus_core as dioxus;
// use dioxus_core::prelude::*;
-// static Example: FC<()> = |cx| {
+// pub static Example: FC<()> = |cx| {
// let list = (0..10).map(|f| LazyNodes::new(move |f| todo!()));
// cx.render(LazyNodes::new(move |cx| {
diff --git a/packages/core/examples/contextapi.rs b/packages/core/examples/contextapi.rs
index 1e6856ce3..61dc79837 100644
--- a/packages/core/examples/contextapi.rs
+++ b/packages/core/examples/contextapi.rs
@@ -5,12 +5,8 @@ struct SomeContext {
items: Vec,
}
-struct Props {
- name: String,
-}
-
#[allow(unused)]
-static Example: FC = |cpt| {
+static Example: FC<()> = |cpt| {
todo!()
// let value = cx.use_context(|c: &SomeContext| c.items.last().unwrap());
diff --git a/packages/core/src/context.rs b/packages/core/src/context.rs
index dbef3052a..27c735e7a 100644
--- a/packages/core/src/context.rs
+++ b/packages/core/src/context.rs
@@ -321,7 +321,10 @@ Any function prefixed with "use" should not be called conditionally.
///
///
///
- pub fn use_task(&self, task_initializer: Init) -> (&TaskHandle, &Option)
+ pub fn use_task(
+ self,
+ task_initializer: Init,
+ ) -> (TaskHandle<'src>, &'src Option)
where
Out: 'static,
Fut: Future + 'static,
@@ -363,7 +366,7 @@ Any function prefixed with "use" should not be called conditionally.
if let Some(val) = hook.task_dump.as_ref().borrow_mut().take() {
hook.value = Some(val);
}
- (&TaskHandle { _p: PhantomData }, &hook.value)
+ (TaskHandle { _p: PhantomData }, &hook.value)
},
|_| {},
)
@@ -463,6 +466,14 @@ impl<'src, P> Context<'src, P> {
}
}
+#[derive(Clone, Copy)]
pub struct TaskHandle<'src> {
_p: PhantomData<&'src ()>,
}
+
+impl<'src> TaskHandle<'src> {
+ pub fn toggle(&self) {}
+ pub fn start(&self) {}
+ pub fn stop(&self) {}
+ pub fn restart(&self) {}
+}
diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs
index f29425d5c..d090f866f 100644
--- a/packages/core/src/nodes.rs
+++ b/packages/core/src/nodes.rs
@@ -266,7 +266,7 @@ impl<'a> NodeFactory<'a> {
}
}
- pub fn virtual_child(
+ pub fn component
(
&self,
component: FC
,
props: P,
diff --git a/packages/hooks/src/usestate.rs b/packages/hooks/src/usestate.rs
index 6e9063b03..901728dd0 100644
--- a/packages/hooks/src/usestate.rs
+++ b/packages/hooks/src/usestate.rs
@@ -123,7 +123,14 @@ impl<'a, T: 'static> UseState<'a, T> {
let slot = self.inner.wip.clone();
Rc::new(move |new| *slot.borrow_mut() = Some(new))
}
+
+ pub fn for_async(&self) -> AsyncUseState {
+ AsyncUseState {
+ wip: self.inner.wip.clone(),
+ }
+ }
}
+
impl<'a, T: 'static + ToOwned> UseState<'a, T> {
pub fn get_mut(self) -> RefMut<'a, T> {
// make sure we get processed
@@ -175,9 +182,55 @@ impl<'a, T: Copy + Sub> SubAssign for UseState<'a, T> {
}
}
+/// MUL
+impl<'a, T: Copy + Mul> Mul for UseState<'a, T> {
+ type Output = T;
+
+ fn mul(self, rhs: T) -> Self::Output {
+ self.inner.current_val.mul(rhs)
+ }
+}
+impl<'a, T: Copy + Mul> MulAssign for UseState<'a, T> {
+ fn mul_assign(&mut self, rhs: T) {
+ self.set(self.inner.current_val.mul(rhs));
+ }
+}
+/// DIV
+impl<'a, T: Copy + Div> Div for UseState<'a, T> {
+ type Output = T;
+
+ fn div(self, rhs: T) -> Self::Output {
+ self.inner.current_val.div(rhs)
+ }
+}
+impl<'a, T: Copy + Div> DivAssign for UseState<'a, T> {
+ fn div_assign(&mut self, rhs: T) {
+ self.set(self.inner.current_val.div(rhs));
+ }
+}
+
// enable displaty for the handle
impl<'a, T: 'static + Display> std::fmt::Display for UseState<'a, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.inner.current_val)
}
}
+
+/// A less ergonmic but still capable form of use_state that's valid for `static lifetime
+pub struct AsyncUseState {
+ wip: Rc>>,
+}
+
+impl AsyncUseState {
+ pub fn get_mut<'a>(&'a self) -> RefMut<'a, T> {
+ // make sure we get processed
+ // self.needs_update();
+
+ // Bring out the new value, cloning if it we need to
+ // "get_mut" is locked behind "ToOwned" to make it explicit that cloning occurs to use this
+ RefMut::map(self.wip.borrow_mut(), |slot| {
+ //
+ slot.as_mut().unwrap()
+ })
+ }
+}
diff --git a/packages/html/src/lib.rs b/packages/html/src/lib.rs
index a08686d3c..9126bed4e 100644
--- a/packages/html/src/lib.rs
+++ b/packages/html/src/lib.rs
@@ -924,6 +924,8 @@ builder_constructors! {
/// [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div)
/// element.
///
+ /// Part of the HTML namespace. Only works in HTML-compatible renderers
+ ///
/// ## Definition and Usage
/// - The
tag defines a division or a section in an HTML document.
/// - The
tag is used as a container for HTML elements - which is then styled with CSS or manipulated with JavaScript.
@@ -1575,6 +1577,7 @@ builder_constructors! {
/// [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select)
/// element.
select {
+ value: String,
autocomplete: String,
autofocus: Bool,
disabled: Bool,
diff --git a/packages/mobile/src/lib.rs b/packages/mobile/src/lib.rs
index aeae63ff3..69e0a73f7 100644
--- a/packages/mobile/src/lib.rs
+++ b/packages/mobile/src/lib.rs
@@ -9,7 +9,8 @@ use wry::application::window::Fullscreen;
use wry::application::{
dpi::LogicalSize,
event::StartCause,
- platform::ios::{ScreenEdge, WindowBuilderExtIOS, WindowExtIOS},
+ // platform::ios::{ScreenEdge, WindowBuilderExtIOS, WindowExtIOS},
+ // platform::ios::{ScreenEdge, WindowBuilderExtIOS, WindowExtIOS},
};
use wry::webview::WebViewBuilder;
use wry::{
@@ -23,7 +24,7 @@ fn init_logging() {
simple_logger::SimpleLogger::new().init().unwrap();
}
-static HTML_CONTENT: &'static str = include_str!("./../../webview/src/index.html");
+static HTML_CONTENT: &'static str = include_str!("../../desktop/src/index.html");
pub fn launch(root: FC<()>, builder: fn(WindowBuilder) -> WindowBuilder) -> anyhow::Result<()> {
launch_with_props(root, (), builder)
diff --git a/packages/ssr/examples/tide.rs b/packages/ssr/examples/tide.rs
index dbed0cd28..37a494b59 100644
--- a/packages/ssr/examples/tide.rs
+++ b/packages/ssr/examples/tide.rs
@@ -38,7 +38,7 @@ struct ExampleProps {
initial_name: String,
}
-static Example: FC = |cx| {
+pub static Example: FC = |cx| {
let dispaly_name = use_state(cx, move || cx.initial_name.clone());
cx.render(rsx! {
diff --git a/packages/ssr/examples/tofile.rs b/packages/ssr/examples/tofile.rs
index 7e7a959b5..963f620dd 100644
--- a/packages/ssr/examples/tofile.rs
+++ b/packages/ssr/examples/tofile.rs
@@ -19,7 +19,7 @@ fn main() {
.unwrap();
}
-pub const App: FC<()> = |cx| {
+pub static App: FC<()> = |cx| {
cx.render(rsx!(
div { class: "overflow-hidden"
link { href:"https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel:"stylesheet" }
@@ -34,7 +34,7 @@ pub const App: FC<()> = |cx| {
))
};
-pub const Header: FC<()> = |cx| {
+pub static Header: FC<()> = |cx| {
cx.render(rsx! {
div {
header { class: "text-gray-400 bg-gray-900 body-font"
@@ -60,7 +60,7 @@ pub const Header: FC<()> = |cx| {
})
};
-pub const Hero: FC<()> = |cx| {
+pub static Hero: FC<()> = |cx| {
//
cx.render(rsx! {
section{ class: "text-gray-400 bg-gray-900 body-font"
@@ -98,7 +98,7 @@ pub const Hero: FC<()> = |cx| {
}
})
};
-pub const Entry: FC<()> = |cx| {
+pub static Entry: FC<()> = |cx| {
//
cx.render(rsx! {
section{ class: "text-gray-400 bg-gray-900 body-font"
@@ -111,7 +111,7 @@ pub const Entry: FC<()> = |cx| {
})
};
-pub const StacksIcon: FC<()> = |cx| {
+pub static StacksIcon: FC<()> = |cx| {
cx.render(rsx!(
svg {
// xmlns: "http://www.w3.org/2000/svg"
@@ -126,7 +126,7 @@ pub const StacksIcon: FC<()> = |cx| {
}
))
};
-pub const RightArrowIcon: FC<()> = |cx| {
+pub static RightArrowIcon: FC<()> = |cx| {
cx.render(rsx!(
svg {
fill: "none"
diff --git a/packages/web/examples/demo.rs b/packages/web/examples/demo.rs
index 875f3b2b0..5c6f99f9a 100644
--- a/packages/web/examples/demo.rs
+++ b/packages/web/examples/demo.rs
@@ -25,7 +25,7 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
}
-pub const App: FC<()> = |cx| {
+pub static App: FC<()> = |cx| {
cx.render(rsx!(
div { class: "overflow-hidden"
link { href:"https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel:"stylesheet" }
@@ -40,7 +40,7 @@ pub const App: FC<()> = |cx| {
))
};
-pub const Header: FC<()> = |cx| {
+pub static Header: FC<()> = |cx| {
cx.render(rsx! {
div {
header { class: "text-gray-400 bg-gray-900 body-font"
@@ -66,7 +66,7 @@ pub const Header: FC<()> = |cx| {
})
};
-pub const Hero: FC<()> = |cx| {
+pub static Hero: FC<()> = |cx| {
//
cx.render(rsx! {
section{ class: "text-gray-400 bg-gray-900 body-font"
@@ -104,7 +104,7 @@ pub const Hero: FC<()> = |cx| {
}
})
};
-pub const Entry: FC<()> = |cx| {
+pub static Entry: FC<()> = |cx| {
//
cx.render(rsx! {
section{ class: "text-gray-400 bg-gray-900 body-font"
@@ -117,7 +117,7 @@ pub const Entry: FC<()> = |cx| {
})
};
-pub const StacksIcon: FC<()> = |cx| {
+pub static StacksIcon: FC<()> = |cx| {
cx.render(rsx!(
svg {
// xmlns: "http://www.w3.org/2000/svg"
@@ -132,7 +132,7 @@ pub const StacksIcon: FC<()> = |cx| {
}
))
};
-pub const RightArrowIcon: FC<()> = |cx| {
+pub static RightArrowIcon: FC<()> = |cx| {
cx.render(rsx!(
svg {
fill: "none"
diff --git a/src/lib.rs b/src/lib.rs
index a7c618f57..5165d0f0b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -93,7 +93,7 @@
//! Dioxus uses hooks for state management. Hooks are a form of state persisted between calls of the function component.
//!
//! ```
-//! static Example: FC<()> = |cx| {
+//! pub static Example: FC<()> = |cx| {
//! let (val, set_val) = use_state(cx, || 0);
//! cx.render(rsx!(
//! button { onclick: move |_| set_val(val + 1) }
@@ -156,7 +156,7 @@
//! diouxs::web::launch(Example);
//! }
//!
-//! static Example: FC<()> = |cx| {
+//! pub static Example: FC<()> = |cx| {
//! cx.render(rsx! {
//! div { "Hello World!" }
//! })
@@ -188,6 +188,8 @@ pub use dioxus_hooks as hooks;
#[cfg(feature = "desktop")]
pub use dioxus_desktop as desktop;
+pub mod debug {}
+
pub mod prelude {
//! A glob import that includes helper types like FC, rsx!, html!, and required traits
pub use dioxus_core::prelude::*;