Merge branch 'DioxusLabs:master' into fix-component-attribute-formatting

This commit is contained in:
ealmloff authored and GitHub committed 2023-03-17 13:07:28 -05:00
commit db79168348
14 files changed
+60 -49

No files matched your search

+1 -1
View File
@@ -40,7 +40,7 @@
<span> | </span> <span> | </span>
<a href="https://github.com/DioxusLabs/example-projects"> Examples </a> <a href="https://github.com/DioxusLabs/example-projects"> Examples </a>
<span> | </span> <span> | </span>
<a href="https://dioxuslabs.com/guide/en/"> Guide </a> <a href="https://dioxuslabs.com/docs/0.3/guide/en/"> Guide </a>
<span> | </span> <span> | </span>
<a href="https://github.com/DioxusLabs/dioxus/blob/master/notes/README/ZH_CN.md"> 中文 </a> <a href="https://github.com/DioxusLabs/dioxus/blob/master/notes/README/ZH_CN.md"> 中文 </a>
<span> | </span> <span> | </span>
+8
View File
@@ -92,6 +92,8 @@ With Coroutines, we can centralize our async logic. The `rx` parameter is an Cha
```rust ```rust
use futures_util::stream::StreamExt;
enum ProfileUpdate { enum ProfileUpdate {
SetUsername(String), SetUsername(String),
SetAge(i32) SetAge(i32)
@@ -117,6 +119,10 @@ cx.render(rsx!{
}) })
``` ```
> Note: In order to use/run the `rx.next().await` statement you will need to extend the [`Stream`] trait (used by [`UnboundedReceiver`]) by adding 'futures_util' as a dependency to your project and adding the `use futures_util::stream::StreamExt;`.
For sufficiently complex apps, we could build a bunch of different useful "services" that loop on channels to update the app. For sufficiently complex apps, we could build a bunch of different useful "services" that loop on channels to update the app.
```rust ```rust
@@ -164,6 +170,8 @@ fn Banner(cx: Scope) -> Element {
Now, in our sync service, we can structure our state however we want. We only need to update the view values when ready. Now, in our sync service, we can structure our state however we want. We only need to update the view values when ready.
```rust ```rust
use futures_util::stream::StreamExt;
enum SyncAction { enum SyncAction {
SetUsername(String), SetUsername(String),
} }
@@ -14,7 +14,7 @@ For example, if many components need to access an `AppSettings` struct, you can
## Custom Hook Logic ## Custom Hook Logic
You can use [`cx.use_hook`](https://docs.rs/dioxus/latest/dioxus/prelude/struct.Scope.html#method.use_hook) to build your own hooks. In fact, this is what all the standard hooks are built on! You can use [`cx.use_hook`](https://docs.rs/dioxus/latest/dioxus/prelude/struct.ScopeState.html#method.use_hook) to build your own hooks. In fact, this is what all the standard hooks are built on!
`use_hook` accepts a single closure for initializing the hook. It will be only run the first time the component is rendered. The return value of that closure will be used as the value of the hook – Dioxus will take it, and store it for as long as the component is alive. On every render (not just the first one!), you will get a reference to this value. `use_hook` accepts a single closure for initializing the hook. It will be only run the first time the component is rendered. The return value of that closure will be used as the value of the hook – Dioxus will take it, and store it for as long as the component is alive. On every render (not just the first one!), you will get a reference to this value.
@@ -22,5 +22,5 @@ You can use [`cx.use_hook`](https://docs.rs/dioxus/latest/dioxus/prelude/struct.
Inside the initialization closure, you will typically make calls to other `cx` methods. For example: Inside the initialization closure, you will typically make calls to other `cx` methods. For example:
- The `use_state` hook tracks state in the hook value, and uses [`cx.schedule_update`](https://docs.rs/dioxus/latest/dioxus/prelude/struct.Scope.html#method.schedule_update) to make Dioxus re-render the component whenever it changes. - The `use_state` hook tracks state in the hook value, and uses [`cx.schedule_update`](https://docs.rs/dioxus/latest/dioxus/prelude/struct.ScopeState.html#method.schedule_update) to make Dioxus re-render the component whenever it changes.
- The `use_context` hook calls [`cx.consume_context`](https://docs.rs/dioxus/latest/dioxus/prelude/struct.Scope.html#method.consume_context) (which would be expensive to call on every render) to get some context from the scope - The `use_context` hook calls [`cx.consume_context`](https://docs.rs/dioxus/latest/dioxus/prelude/struct.ScopeState.html#method.consume_context) (which would be expensive to call on every render) to get some context from the scope
+6 -5
View File
@@ -1,10 +1,11 @@
# Dioxus Router: Introduction # Dioxus Router: Introduction
Whether or not you're building a website, desktop app, or mobile app, organizing your app's views into "pages" can be an effective method for organization and maintainability. Whether or not you're building a website, desktop app, or mobile app, organizing your app's views into "pages" can be an effective method for organization and maintainability.
Dioxus comes with a router built-in. To start utilizing Dioxus Router, enable the ``router`` feature in your ``Cargo.toml`` file. The `dioxus-router` crate contains the Router module. To add it to your project run:
```toml
[dependencies] cargo add dioxus-router
dioxus = { version = "x.x.x", features = [.., "router"] }
``` > **Be sure to include the `web` feature (`--feature web`) for deployment into a browser!**
In this book you'll find a short [guide](./guide/index.md) to get up to speed with Dioxus Router, as well as the router's [reference](./reference/index.md). In this book you'll find a short [guide](./guide/index.md) to get up to speed with Dioxus Router, as well as the router's [reference](./reference/index.md).
+3 -3
View File
@@ -175,10 +175,10 @@ impl VirtualDom {
} }
impl ElementPath { impl ElementPath {
pub(crate) fn is_ascendant(&self, big: &&[u8]) -> bool { pub(crate) fn is_decendant(&self, small: &&[u8]) -> bool {
match *self { match *self {
ElementPath::Deep(small) => small.len() <= big.len() && small == &big[..small.len()], ElementPath::Deep(big) => small.len() <= big.len() && *small == &big[..small.len()],
ElementPath::Root(r) => big.len() == 1 && big[0] == r as u8, ElementPath::Root(r) => small.len() == 1 && small[0] == r as u8,
} }
} }
} }
+3 -3
View File
@@ -72,9 +72,9 @@ pub struct LocalTaskHandle {
impl ArcWake for LocalTaskHandle { impl ArcWake for LocalTaskHandle {
fn wake_by_ref(arc_self: &Arc<Self>) { fn wake_by_ref(arc_self: &Arc<Self>) {
arc_self // This can fail if the scheduler has been dropped while the application is shutting down
let _ = arc_self
.tx .tx
.unbounded_send(SchedulerMsg::TaskNotified(arc_self.id)) .unbounded_send(SchedulerMsg::TaskNotified(arc_self.id));
.unwrap();
} }
} }
+1 -1
View File
@@ -396,7 +396,7 @@ impl VirtualDom {
// Remove the "on" prefix if it exists, TODO, we should remove this and settle on one // Remove the "on" prefix if it exists, TODO, we should remove this and settle on one
if attr.name.trim_start_matches("on") == name if attr.name.trim_start_matches("on") == name
&& target_path.is_ascendant(&this_path) && target_path.is_decendant(&this_path)
{ {
listeners.push(&attr.value); listeners.push(&attr.value);
+5
View File
@@ -271,6 +271,11 @@ impl DesktopContext {
self.shortcut_manager.remove_shortcut(id) self.shortcut_manager.remove_shortcut(id)
} }
/// Remove all global shortcuts
pub fn remove_all_shortcuts(&self) {
self.shortcut_manager.remove_all()
}
/// Push an objc view to the window /// Push an objc view to the window
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
pub fn push_view(&self, view: objc_id::ShareId<objc::runtime::Object>) { pub fn push_view(&self, view: objc_id::ShareId<objc::runtime::Object>) {
+12
View File
@@ -113,6 +113,18 @@ impl ShortcutRegistry {
} }
} }
} }
pub(crate) fn remove_all(&self) {
let mut shortcuts = self.shortcuts.borrow_mut();
shortcuts.clear();
let _ = self.manager.borrow_mut().unregister_all();
// prevent CTRL+R from reloading the page which breaks apps
let _ = self.add_shortcut(
Some(ModifiersState::CONTROL),
KeyCode::KeyR,
Box::new(|| {}),
);
}
} }
#[non_exhaustive] #[non_exhaustive]
+11 -11
View File
@@ -37,7 +37,16 @@ impl LiveViewPool {
app: fn(Scope<T>) -> Element, app: fn(Scope<T>) -> Element,
props: T, props: T,
) -> Result<(), LiveViewError> { ) -> Result<(), LiveViewError> {
match self.pool.spawn_pinned(move || run(app, props, ws)).await { self.launch_virtualdom(ws, move || VirtualDom::new_with_props(app, props))
.await
}
pub async fn launch_virtualdom<F: FnOnce() -> VirtualDom + Send + 'static>(
&self,
ws: impl LiveViewSocket,
make_app: F,
) -> Result<(), LiveViewError> {
match self.pool.spawn_pinned(move || run(make_app(), ws)).await {
Ok(Ok(_)) => Ok(()), Ok(Ok(_)) => Ok(()),
Ok(Err(e)) => Err(e), Ok(Err(e)) => Err(e),
Err(_) => Err(LiveViewError::SendingFailed), Err(_) => Err(LiveViewError::SendingFailed),
@@ -95,14 +104,7 @@ impl<S> LiveViewSocket for S where
/// As long as your framework can provide a Sink and Stream of Strings, you can use this function. /// As long as your framework can provide a Sink and Stream of Strings, you can use this function.
/// ///
/// You might need to transform the error types of the web backend into the LiveView error type. /// You might need to transform the error types of the web backend into the LiveView error type.
pub async fn run<T>( pub async fn run(mut vdom: VirtualDom, ws: impl LiveViewSocket) -> Result<(), LiveViewError> {
app: Component<T>,
props: T,
ws: impl LiveViewSocket,
) -> Result<(), LiveViewError>
where
T: Send + 'static,
{
#[cfg(all(feature = "hot-reload", debug_assertions))] #[cfg(all(feature = "hot-reload", debug_assertions))]
let mut hot_reload_rx = { let mut hot_reload_rx = {
let (tx, rx) = tokio::sync::mpsc::unbounded_channel(); let (tx, rx) = tokio::sync::mpsc::unbounded_channel();
@@ -112,8 +114,6 @@ where
rx rx
}; };
let mut vdom = VirtualDom::new_with_props(app, props);
// todo: use an efficient binary packed format for this // todo: use an efficient binary packed format for this
let edits = serde_json::to_string(&vdom.rebuild()).unwrap(); let edits = serde_json::to_string(&vdom.rebuild()).unwrap();
+1 -1
View File
@@ -1,4 +1,4 @@
# Dioxus Native Core # Dioxus Router
[![Crates.io][crates-badge]][crates-url] [![Crates.io][crates-badge]][crates-url]
[![MIT licensed][mit-badge]][mit-url] [![MIT licensed][mit-badge]][mit-url]
+2 -7
View File
@@ -46,18 +46,13 @@ impl Default for Config {
} }
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy, Default)]
pub enum RenderingMode { pub enum RenderingMode {
/// only 16 colors by accessed by name, no alpha support /// only 16 colors by accessed by name, no alpha support
BaseColors, BaseColors,
/// 8 bit colors, will be downsampled from rgb colors /// 8 bit colors, will be downsampled from rgb colors
Ansi, Ansi,
/// 24 bit colors, most terminals support this /// 24 bit colors, most terminals support this
#[default]
Rgb, Rgb,
} }
impl Default for RenderingMode {
fn default() -> Self {
RenderingMode::Rgb
}
}
+2 -7
View File
@@ -14,8 +14,9 @@ use dioxus_native_core::{
state::NodeDepState, state::NodeDepState,
}; };
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
pub(crate) enum FocusLevel { pub(crate) enum FocusLevel {
#[default]
Unfocusable, Unfocusable,
Focusable, Focusable,
Ordered(std::num::NonZeroU16), Ordered(std::num::NonZeroU16),
@@ -53,12 +54,6 @@ impl Ord for FocusLevel {
} }
} }
impl Default for FocusLevel {
fn default() -> Self {
FocusLevel::Unfocusable
}
}
#[derive(Clone, PartialEq, Debug, Default)] #[derive(Clone, PartialEq, Debug, Default)]
pub(crate) struct Focus { pub(crate) struct Focus {
pub level: FocusLevel, pub level: FocusLevel,
+2 -7
View File
@@ -20,7 +20,7 @@ pub(crate) struct NodeState {
pub focused: bool, pub focused: bool,
} }
#[derive(PartialEq, Debug, Clone)] #[derive(PartialEq, Debug, Clone, Default)]
pub(crate) enum PreventDefault { pub(crate) enum PreventDefault {
Focus, Focus,
KeyPress, KeyPress,
@@ -32,6 +32,7 @@ pub(crate) enum PreventDefault {
MouseEnter, MouseEnter,
MouseLeave, MouseLeave,
MouseOut, MouseOut,
#[default]
Unknown, Unknown,
MouseOver, MouseOver,
ContextMenu, ContextMenu,
@@ -39,12 +40,6 @@ pub(crate) enum PreventDefault {
MouseUp, MouseUp,
} }
impl Default for PreventDefault {
fn default() -> Self {
PreventDefault::Unknown
}
}
impl NodeDepState for PreventDefault { impl NodeDepState for PreventDefault {
type DepState = (); type DepState = ();
type Ctx = (); type Ctx = ();