dioxuslabs / dioxus Goto Github PK
View Code? Open in Web Editor NEWFullstack GUI library for web, desktop, mobile, and more.
Home Page: https://dioxuslabs.com
License: Apache License 2.0
Fullstack GUI library for web, desktop, mobile, and more.
Home Page: https://dioxuslabs.com
License: Apache License 2.0
The example code doesn't show the config builder function that's required.
Instead of putting dioxus IDs on all elements, we should just put IDs on elements with listeners attached to them, and then walk the tree when an event is triggered to find a valid element to trigger.
Docs
Technical
Ecosystem
Release
Blockers
let rendered = "html object"
rsx!(cx,
div { class: "prose lg:prose-xl",
rendered
})
but not work~
onsubmit
FormData value is just can get the form
element attr: value
, but is not for the all form-data
, like:
<form id="x_form" value="XXX_VALUE">
<input name="test-1" />
<input name="test-2" />
</form>
for the submit, we need get all form in this element, like test-1
and test-2
value, but its just can get the value of "XXX_VALUE"
In the docs, the event handler bind like:
#[derive(Props)]
struct ClickableProps<'a> {
onclick: EventHandler<'a, MouseEvent>
}
fn clickable(cx: Scope<ClickableProps>) -> Element {
cx.render(rsx!(
a {
onclick: move |evt| cx.props.onclick.call(evt)
}
))
}
But in the current version, the EventHandler
don't need the second arg: MouseEvent
, and the evt
type is UiEvent<MouseData>
but the onclick.call
must be have the type of AnyEvent
.
Because tags are 'static
, they currently are not pushed through the formatting infrastructure in the macro. We should change tag to be 'a
so we can use runtime-determined tags.
Running a basic "Hello World" app in Linux I notices a bunch of strange stuff going on:
The menus might be intended, but reload breaking stuff is clearly not.
Currently the web and webview share different interpreter code - it would be nice to move to either a completely wasm-based interpreter or a pure JavaScript/TypeScript interpreter. The appropriate steps have been taken - JS code refactored out and event system is now configured to always use serialized events.
Cannot use disabled
attribute like:
// cx.props.disabled = true
button {
disabled: "{cx.props.disabled}",
"Button",
}
the button
state always be disabled
.
but you can use this code to do it:
let is_disabled = if disabled { "disabled" } else { "" };
rsx!{
"{is_disabled}": "true"
}
For windows users, they must have webview2. This is not so insurmountable.
https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution
We can either package webview with the app or send along a bootstrapper.
Other apps have done this before, so maybe we can steal some thoughts from them.
What are people's general thoughts regarding webview2 access on Windows? Should we just fallback to MSHTML if the user doesn't have edge installed?
The VirtualDom is not Send
which makes it challenging to hold across await points in web frameworks for liveview or SSR.
Either we need to develop our own web framework (with the same level of ergonomics of Diouxs) or somehow get the VirtualDom threadsafe to Send
across threads.
Package related : web
Context: runtime
I have a runtime error stating that cx.consume_context::<RouterService>()
is already borrowed.
I know where in my code it has been borrowed but how to release and avoid this runtime error?
It happens in this piece of code:
onclick: move |_| {
cx.consume_context::<RouterService>().as_ref().unwrap().push_route("/")
}
I'm using consume_context
in another component of my app so I understand the error but how avoid this already borrowed runtime error?
Congratulation! This is a very impressive approach to UI.
I was wondering if a comparison with Azul GUI Framework makes sense.
Coping content from: https://old.reddit.com/r/rust/comments/rv9hru/releasing_dioxus_v01_a_new_rust_gui_toolkit_for/hrc0gbz/?context=3
prabirshrestha:
This looks awesome. Are the plans to support platform native ui frameworks such as gtk-rs and UIKit? Having all controls would cause maintenance headache but I think having example on how to use Gtk-rs with dioxus with few controls would be a good start. This would allow me to easily create dioxus components backed by gtk-rs.
I think this has a potential to take over react-native if it can support platform native controls. Having core component abstraction such as View, Text, Image could be a good start. https://reactnative.dev/docs/components-and-apis#basic-components
Would love to see an official support for platform native ui components that doesn't depend on html and javascript.
jkelleyrtp:
That's the plan! To pop the hood open a little bit, we have a type calledMutations
which essentially describes what needs to be patched in the real renderer to make it look like the VirtualDom's understanding of the world.
https://github.com/DioxusLabs/dioxus/blob/master/packages/core/src/mutations.rs
You can implement entirely new elements, attributes, and listeners that integrate with thersx!
macro. Right now, the HTML namespace is supported through a collection of zero-sized-types and some traits to make things fit together:
https://docs.rs/dioxus-html/0.1.3/dioxus\_html/
If you wanted to add a new fundamental language to rsx!, or even just components, it's entirely possible. I'd love to see native macOS / GTK / win apps using the same set of common primitives.
(creating this issue so I can subscribe to it and get notified on updates).
I'm personally interested in native platform ui without html and javascript.
For gtk-rs here are some good references:
ui kit resources:
As part of subtrees, we should implement "Subtree Attributes" to drive platform-specific things like the document title, head, meta tags, etc.
This can let us implement cross-platform abstractions around things like location so we can have our router code work the same even across the net (for liveview).
Right now, if you click on a link in Dioxus Desktop, the webview will try to link within the webview. However, that's not at all how Dioxus apps should work: all external links should open in the web browser.
Hey,
was trying out Dioxus. looks excellet so far really well done 👍
was thinking is there any way dioxus support HMR? tools like tauri
rely on other dev server to provide updated code immediately
but not sure if same can be achieved with dioxus? since on every
change closing app and reopening is a bit tedious!
a {
role: "button",
class: "navbar-item",
href: "/",
"aria-label": "menu",
"aria-expanded": "false",
"data-target": "navbarMainMenu",
prevent_default: "onclick",
onclick: move |_| {cl.set(!cl)},
img {
src: "https://bulma.io/images/bulma-logo.png",
width: "112",
height: "28"
}
}
when the img onclick, will redirect, the prevent_default is not take effect.
from: Discord Discussion
Any examples of using the canvas to draw graphics?
Hi there, have you noticed the examples/todomvc.rs seemed not to function, each item could not be checked, thus there is no way to make a item to be completed.
While passing a string (from html input element) up to a parent node, the program sometimes crashes trying to mutate a cell that's currently being mutated.
It's unclear to me exactly why the crash is occuring, the following revealed nothing useful:
I will concede that the code generating this crash is prototype-grade. However, all compiler and clippy lints pass (except non_snake_case due to dioxus style).
My speculation is that this has to do with my "onsend" propery not using the correct bounds, or requiring some wrapper, but I don't have a solution yet.
Rust Target: x86_64-unknown-linux-gnu
Rust Version: 1.57.0 (rustup installed)
Linux Version: 5.14.21-2-MANJARO
I haven't tried on any other platforms.
I find when trigger a event like click
, the rpc.call
will send the event
as a UserEvent
, but the onclick
callback get the UIEvent
, it only includes a data
attribute with type MouseEvent
How does it design?
I just think if I want to get the element position like the html element which can use getBoundingClientRect
to get top
, left
...
Unfortunately, there's no way today to conditionally call PreventDefault across the Tao/Wry boundary.
Developers should be able to disable default in a way that's not just hardcoded fields - IE allowing default behavior when right-clicking links in the browser.
The FFI boundary is particularly challenging because we cannot synchronously handle the event.
I think the solution is to always trap the event and prevent default.
Then, ff 1) the event has default behavior and 2) the user didn't prevent that default behavior in their Dioxus handler, then we should craft the event again and push it back in the real dom.
dioxus/packages/core/src/scopes.rs
Lines 799 to 829 in fa70dd5
Currently, rustfmt
fails on code using the rsx!
macro. Would it be possible for this to work?
Alternatively, is there any way to create markup without using the macro?
So the comparison in README needs to update :D
In the web, we use wasm-bindgens intern
feature to cache strings on the js/rust boundary. However, this approach forces us to come up with a list of strings at compile-time. Instead, we should implement our own interning feature that uses a bloom filter and a configurable amount of cached elements, or some sort of better heuristic (like length). The time to cache/uncache is pretty significant in benchmarks, and it's unnatural to tell users to pre-populate the string cache if they want good performance.
I've been working with Futures and Dioxus and am having a lot of trouble getting my futures to re-load. I'm trying to a flow similar to a browser where there is a URL bar at the top, and the content is reloaded when the URL changes.
The problem I'm having is that if I have content being loaded from a Future, I have to manually notice that the parameters I'm passing into the future have been invalidated and call restart on it. Here's a stripped version of what I'm working on:
fn app(cx: Scope) -> Element {
let state = use_state(&cx, || ClientState::Disconnected);
let url = use_state(&cx, || String::from("ws://localhost:8080/ws"));
let client_url = use_state(&cx, || Option::<Url>::None);
let client = if let ClientState::Connected(url) = state.get() {
let url = url.clone();
Some(use_future(&cx, || async move {
let url = dbg!(Url::parse(&url).map_err(|err| err.to_string())?);
Client::build(url)
.finish()
.await
.map_err(|err| err.to_string())
}))
} else {
None
};
cx.render(rsx! {
div {
class: "container m-3",
match state.get() {
ClientState::Disconnected => {
cx.render(rsx!{"Connect to a BonsaiDb server."})
}
ClientState::Connected(_) => {
cx.render(
match client.and_then(|c| c.value()) {
Some(Ok(client)) => {
rsx!(list_databases(client: client))
}
Some(Err(err)) => {
alert(err, "alert-danger")
},
None => rsx!{ div{ "loading..." } }
}
)
}
}
}
})
}
#[derive(Props)]
struct ListDatabaseProps<'a> {
client: &'a Client,
}
fn list_databases<'a>(cx: Scope<'a, ListDatabaseProps<'a>>) -> Element<'a> {
let client = cx.props.client.clone();
let databases = use_future(&cx, || async move { dbg!(client.list_databases().await) });
cx.render(match databases.value() {
Some(Ok(databases)) =>{...}
Some(Err(err)) => alert(err, "alert-danger"),
None => rsx! { div { "loading databases" }},
})
}
When the URL changes, I get a new client (confirmed via debug logging), but the future in list_databases doesn't restart. To make this work I'll have to detect that the client has changed manually and restart the future.
Is there a way to be able to tie the use_future to depend on another UseState, so that it automatically restarts when that state is invalidated?
I have to make a component, but I want set some field to optional, that mean is if the render
don't have give the field value, then I can give it a default value.
I think the EventHandler
must have a Default
tarit, because I think its optional.
Just tried to do the hello world example for windows and got a not implemented panic:
thread 'main' panicked at 'not implemented: path index.html/',[PATH]\dioxus-desktop-0.1.3\src\lib.rs:347:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
webview2: panic in callback function. Aborting because it's UB to unwind across FFI boundaries.
error: process didn't exit successfully: `target\debug\hello.exe` (exit code: 0xc0000409, STATUS_STACK_BUFFER_OVERRUN)
main.rs
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(App);
}
fn App(cx: Scope) -> Element {
cx.render(rsx! (
div { "Hello, world!" }
))
}
[dependencies]
dioxus = { version = "0.1.5", features = ["desktop"] }
Tried the example a few times, each time cleaning and starting fresh with the same result. Can add more info if you need, bit new to adding issues to repos.
hello,i'm writing an app using dioxus, but I have some difficulties:
button { class: "bg-red-500 m-1 w-3 h-3 rounded-full",
onclick: move |evt| {
// TODO: app exit
println!("close windows:{:?}",evt);
}
}
I can only handle events of a certain tag now, but sometimes have to deal with system some shortcut keys
$('#image').click(function() {
$('#foo').addClass('myClass');
});
I receive the following errors when I try and install this cli tooling for dioxus via cargo install dioxus-cli
:
Compiling dioxus-cli v0.1.0
error[E0599]: no function or associated item named `new_immediate` found for trait object `dyn notify::Watcher` in the current scope
--> /home/ed/.cargo/registry/src/github.com-1ecc6299db9ec823/dioxus-cli-0.1.0/src/develop.rs:43:52
|
43 | let mut watcher: RecommendedWatcher = Watcher::new_immediate(move |res| {
| ^^^^^^^^^^^^^ function or associated item not found in `dyn notify::Watcher`
error[E0308]: mismatched types
--> /home/ed/.cargo/registry/src/github.com-1ecc6299db9ec823/dioxus-cli-0.1.0/src/develop.rs:53:16
|
53 | .watch(src_dir.join("src"), RecursiveMode::Recursive)
| ^^^^^^^^^^^^^^^^^^^
| |
| expected `&std::path::Path`, found struct `std::path::PathBuf`
| help: consider borrowing here: `&src_dir.join("src")`
error[E0308]: mismatched types
--> /home/ed/.cargo/registry/src/github.com-1ecc6299db9ec823/dioxus-cli-0.1.0/src/develop.rs:57:16
|
57 | .watch(src_dir.join("examples"), RecursiveMode::Recursive)
| ^^^^^^^^^^^^^^^^^^^^^^^^
| |
| expected `&std::path::Path`, found struct `std::path::PathBuf`
| help: consider borrowing here: `&src_dir.join("examples")`
Some errors have detailed explanations: E0308, E0599.
For more information about an error, try `rustc --explain E0308`.
error: could not compile `dioxus-cli` due to 3 previous errors
warning: build failed, waiting for other jobs to finish...
error: failed to compile `dioxus-cli v0.1.0`, intermediate artifacts can be found at `/tmp/cargo-installUlWQ20`
Caused by:
build failed
I'm currently running Windows 10, but performed the above in WSL 2, in an Ubuntu VM. Some details about my system:
Edition Windows 10 Pro
Version 21H2
Installed on 2021-11-18
OS build 19044.1415
Experience Windows Feature Experience Pack 120.2212.3920.0
It should be possible to access the native event that caused the event listener to fire in Dioxus web.
Unfortunately there's no way to access the event natively in Dioxus Desktop (webview) - though we could hold the event in stasis and provide some wrappers through FFI.
After installing webview2 runtime, the demo worked. But in the demo file-explorer, it took several seconds to display the result. And the exe generated a folder called file-explorer.exe.WebView2, and there were many files inside.
The following does not render the image correctly.
rsk! {
cx,
img { src: "src/assets/images/logo.png" }
}
It results in a broken link like this ...
The broken image has the following url link https://wry.index.html/src/assets/images/logo.png
None of these worked either
src/assets/images/logo.png
/src/assets/images/logo.png
/assets/images/logo.png
assets/images/logo.png
Is it possible to use a local image resource?
If so, how? I have not been able to find any examples that have local images.
Thanks for the help
Reminiscent of:
Andarist/react-textarea-autosize#100
If we update an input value twice in one frame, we get cursor jumping. This is because of rAF batching the two updates that happened in one frame. In reality, if we get a "synchronous" event, then it should be handled synchronously.
... the joys of following the footsteps of others.
To fix in web, we need to progress the VirtualDom from within the handler. Specifically for inputs/textareas.
To fix in desktop, we need to explicitly segment the two updates across frames, or nullify the first update.
For now, the problem is fixed enough in both platforms that it only appears during key spam.
I encountered the problem when I try to launch the demo in Mac OS, the details below:
error: linking with cc
failed: exit status: 1
= note: Undefined symbols for architecture x86_64:
"_UCKeyTranslate", referenced from:
tao::platform_impl::platform::event::get_modifierless_char::h82c48132d8e4db04 in libtao-4d0591e38d01f123.rlib(tao-4d0591e38d01f123.tao.f570f3ca-cgu.2.rcgu.o)
"_CGDisplayCreateUUIDFromDisplayID", referenced from:
_$LT$tao..platform_impl..platform..monitor..MonitorHandle$u20$as$u20$core..cmp..PartialEq$GT$::eq::h2b490f1950e1775b in libtao-4d0591e38d01f123.rlib(tao-4d0591e38d01f123.tao.f570f3ca-cgu.0.rcgu.o)
tao::platform_impl::platform::monitor::MonitorHandle::ns_screen::h7a220b61d2167bf2 in libtao-4d0591e38d01f123.rlib(tao-4d0591e38d01f123.tao.f570f3ca-cgu.0.rcgu.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Please help me and explain the reason if possible
Thank you very much for making such a wonderful crate.
Does dioxus support <input type="file">
?
From what little research I've done, dioxus-desktop
and others don't seem to support it.
My idea is to handle wry::WebViewBuilder::with_file_drop_handler
properly and create dioxus
own events to handle it.
HTML's Document
has some important goodies that we should allow exposed in a cross-platform way between web and desktop.
https://www.w3schools.com/jsref/dom_obj_document.asp
Right now, to use Document
in the web, you have to go through websys/gloo. However, to use it in Desktop, you would have to assemble some javascript on the desktop side. We should provide a unified hook or something similar that abstracts over Document
functionality for all platforms - so we can set things like title in a cross-platform way.
Excited to try it out so had a crack at the hello world example on Windows just now and it causes an ICE:
onsubmit
FormData value is just can get the form
element attr: value
, but is not for the all form-data
, like:
<form id="x_form" value="XXX_VALUE">
<input name="test-1" />
<input name="test-2" />
</form>
for the submit, we need get all form in this element, like test-1
and test-2
value, but its just can get the value of "XXX_VALUE"
A major performance feature of Dioxus is complete elimination of static subtrees. So, subtrees within rsx!
calls that have no dynamic calls can be "constified" and would be extremely cheap to generate.
This means that entirely-static structures like
thead {
tr { class: "text-xs text-gray-500 text-left",
th { class: "pb-3 font-medium", "Transaction ID" }
th { class: "pb-3 font-medium", "Date" }
th { class: "pb-3 font-medium", "E-mail" }
th { class: "pb-3 font-medium", "Subscription" }
th { class: "pb-3 font-medium", "Status" }
}
}
Would be completely skipped during the diffing process.
We can implement this today but there is some safety considerations to be aware of when hashing these structures. Primarily, if we compare two hashes and the second hash was manually created to be the same as another tree, then we would fail to update call functions for components, leading to missing state/unconnected lifetimes.
You would need to craft these structures intentionally, so it's extremely unlikely for any issue to pop up, but we don't want to directly expose a guaranteed way of causing UB into user code.
How hard would it be to make an application with SCSS? Is that already posible or maybe planned?
I find if I call a function in app init, and if this function will change some state
in app, then the app will infinite-loop
, I think this problem we need prevent.
fn app(cx: Scope) -> Element {
let text = use_read(&cx, TEXT);
todo_function(&cx);
cx.render(rsx!(
h1 { "{text}" }
))
}
I think this problem need developer attention, so I write this issue
qwq
A huge opportunity for Dioxus is to leverage templates on the HTML side to beat out regular Dom patching.
Right now, we send streams of patches from the VDOM into the renderer. This means that we're constantly building the same structures over and over and over, even if they're exactly the same.
For structures like:
rsx!(
tr { class: "text-xs {is_even}", key: "{asin}"
td { class: "py-5 px-6 font-medium", "{asin}" }
td { class: "font-medium", "{Product_Details}" }
td { class: "font-medium", "[email protected]" }
td { class: "font-medium", "Monthly" }
td {
span { class: "inline-block py-1 px-2 text-white bg-green-500 rounded-full",
"Completed"
}
}
}
)
We could save the entire rsx! call as a template and then clone that template whenever this call is rendered. Instead of building the entire template from scratch, we would simply clone an existing iteration of this template and then modify it only in the places where content is different.
The precursor of this work would be #39 where we can actually identify these structures.
This feature is how the Vanilla JS framework benchmark is so fast - they just clone the same templates into place.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.