Renderers are now packages, not features. (#387)

* feat: use synchronous router design

* feat: function to get router out of dom

* chore: restructure workspace to use renderers as packages, not features
This commit is contained in:
Jon Kelley authored and GitHub committed 2022-07-09 15:15:20 -04:00
1 parent c97ca7dff6
commit d9546d9504
181 files changed
+487 -1463

No files matched your search

+1 -1
View File
@@ -1,7 +1,7 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+1 -1
View File
@@ -1,7 +1,7 @@
use dioxus::{events::*, prelude::*};
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
#[derive(Debug)]
+1 -1
View File
@@ -19,7 +19,7 @@ and is proven to be safe with MIRI.
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+3 -3
View File
@@ -4,12 +4,12 @@ This calculator version uses React-style state management. All state is held as
*/
use dioxus::events::*;
use dioxus::html::input_data::keyboard_types::Key;
use dioxus::prelude::*;
use dioxus_html::input_data::keyboard_types::Key;
fn main() {
use dioxus::desktop::tao::dpi::LogicalSize;
dioxus::desktop::launch_cfg(app, |cfg| {
use dioxus_desktop::tao::dpi::LogicalSize;
dioxus_desktop::launch_cfg(app, |cfg| {
cfg.with_window(|w| {
w.with_title("Calculator Demo")
.with_resizable(false)
-21
View File
@@ -1,21 +0,0 @@
# Reference Guide
This folder holds a bunch of useful reference code. However, none of the code is meant to be executed (nothing special will happen).
| Reference: | What it does |
| --------------------------------------------------- | ------------------------------------------------------ |
| [Basics](./basics.rs) | How to render a simple app |
| [Empty](./empty.rs) | Components can return None |
| [Children](./children.rs) | Components can have children |
| [Suspense](./suspense.rs) | Suspense can be achieved with use_suspense |
| [Conditional Rendering](./conditional_rendering.rs) | Elements can be hidden conditionally |
| [Controlled Inputs](./controlled_inputs.rs) | Inputs are "controlled" similar to React |
| [Fragments](./fragments.rs) | Components can return multiple elements without a root |
| [Inline Styles](./inline_styles.rs) | Styles can be inlined as element attributes |
| [Spread Pattern for Props](./spreadpattern.rs) | Props can be spread into component calls |
| [Iterators](./iterators.rs) | Lists of elements can be made from iterators |
| [Listener](./listener.rs) | State can be updated from event listeners |
| [Memo](./memo.rs) | Memoization is controlled via PartialEq |
| [Custom Elements](./custom_elements.rs) | Define custom elements |
| [Anti-patterns](./antipatterns.rs) | What not to do! |
@@ -1,44 +0,0 @@
//! Example: Web Components & Custom Elements
//! -----------------------------------------
//!
//! 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. :(
use dioxus::prelude::*;
pub fn Example(cx: Scope) -> Element {
cx.render(rsx! {
div {
custom_element {
custom_attr: "custom data on custom elements"
}
}
})
}
mod dioxus_elements {
use std::fmt::Arguments;
use dioxus::prelude::DioxusElement;
#[allow(non_camel_case_types)]
pub struct custom_element;
impl DioxusElement for custom_element {
const TAG_NAME: &'static str = "custom_element";
const NAME_SPACE: Option<&'static str> = None;
}
impl custom_element {
pub fn custom_attr<'a>(&self, f: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
f.attr("custom_asttr", val, None, false)
}
}
// Re-export the normal html namespace
pub use dioxus::prelude::dioxus_elements::*;
use dioxus_core::{nodes::Attribute, NodeFactory};
}
-89
View File
@@ -1,89 +0,0 @@
//! Example: Error Handling
//! ------------------------
//!
//! Error handling in Dioxus comes in a few flavors. Because Dioxus is a Rust project, Options and Results are obviously
//! the go-to way of wrapping possibly-errored data. However, if a component fails when "unwrapping," everything will crash,
//! the page will deadlock, and your users will be sad.
//!
//! So, obviously, you need to handle your errors.
//!
//! Fortunately, it's easy to avoid panics, even during quick prototyping.
//!
//! Here are a few strategies:
//! - Leverage the ability to return "None" and propagate None directly
//! - Instead of propagating "None" manually, use the "?" syntax sugar
//! - Convert Results into Options with .ok()
//! - Manually display a separate screen by matching on Options/Results
//!
//! There *are* plans to add helpful screens for when apps completely panic in Wasm. However, you should really try to
//! avoid panicking.
use dioxus::prelude::*;
fn main() {}
/// This is one way to go about error handling (just toss things away with unwrap).
/// However, if you get it wrong, the whole app will crash.
/// This is pretty flimsy.
pub fn App(cx: Scope) -> Element {
let data = get_data().unwrap();
cx.render(rsx!( div { "{data}" } ))
}
/// This is a pretty verbose way of error handling
/// However, it's still pretty good since we don't panic, just fail to render anything
pub fn App1(cx: Scope) -> Element {
let data = match get_data() {
Some(data) => data,
None => return None,
};
cx.render(rsx!( div { "{data}" } ))
}
/// This is an even better form of error handling.
/// However, it _does_ make the component go blank, which might not be desirable.
///
/// This type of error handling is good when you have "selectors" that produce Some/None based on some state that's
/// already controlled higher in the tree. i.e. displaying a "Username" in a component that should only be shown if
/// a user is logged in.
///
/// Dioxus will throw an error in the console if the None-path is ever taken.
pub fn App2(cx: Scope) -> Element {
let data = get_data()?;
cx.render(rsx!( div { "{data}" } ))
}
/// This is top-tier error handling since it displays a failure state.
///
/// However, the error is lacking in context.
pub fn App3(cx: Scope) -> Element {
match get_data() {
Some(data) => cx.render(rsx!( div { "{data}" } )),
None => cx.render(rsx!( div { "Failed to load data :(" } )),
}
}
/// For errors that return results, it's possible to short-circuit the match-based error handling with `.ok()` which converts
/// a Result<T, V> into an Option<T> and lets you abort rendering by early-returning `None`
pub fn App4(cx: Scope) -> Element {
let data = get_data_err().ok()?;
cx.render(rsx!( div { "{data}" } ))
}
/// This is great error handling since it displays a failure state... with context!
///
/// Hopefully you'll never need to display a screen like this. It's rather bad taste
pub fn App5(cx: Scope) -> Element {
match get_data_err() {
Ok(data) => cx.render(rsx!( div { "{data}" } )),
Err(c) => cx.render(rsx!( div { "Failed to load data: {c}" } )),
}
}
// this fetching function produces "nothing"
fn get_data() -> Option<String> {
None
}
// this fetching function produces "nothing"
fn get_data_err() -> Result<String, &'static str> {
Result::Err("Failed!")
}
-30
View File
@@ -1,30 +0,0 @@
//! Examples: CSS
//! -------------
//!
//! Originally taken from:
//! - https://www.w3schools.com/html/tryit.asp?filename=tryhtml_css_internal
//!
//! Include global styles in your app!
//!
//! You can simply drop in a "style" tag and set the inner contents to your stylesheet.
//! It's slightly more manual than React, but is less magical.
//!
//! A coming update with the assets system will make it possible to include global css from child components.
use dioxus::prelude::*;
const STYLE: &str = r#"
body {background-color: powderblue;}
h1 {color: blue;}
p {color: red;}
"#;
pub fn Example(cx: Scope) -> Element {
cx.render(rsx! {
head { style { "{STYLE}" } }
body {
h1 {"This is a heading"}
p {"This is a paragraph"}
}
})
}
-29
View File
@@ -1,29 +0,0 @@
//! Example: Inline Styles
//! ----------------------
//!
//! This example shows how to use inline styles in Dioxus components.
//!
//! Inline styles function very similarly to regular attributes, just grouped together in "style".
//!
//! Inline styles in Dioxus are more performant than React since we're able to cache attributes and compare by pointers.
//! However, it's still not as performant as cascaded styles. Use with care.
use dioxus::prelude::*;
pub fn Example(cx: Scope) -> Element {
cx.render(rsx! {
head {
background_color: "powderblue"
}
body {
h1 {
color: "blue",
"This is a heading"
}
p {
color: "red",
"This is a paragraph"
}
}
})
}
-84
View File
@@ -1,84 +0,0 @@
//! Example: Memoization
//! --------------------
//!
//! This example showcases how memoization works in Dioxus.
//!
//! Memoization is the process in which Dioxus skips diffing child components if their props don't change.
//! In React, components are never memoized unless wrapped in `memo` or configured with `shouldComponentUpdate`.
//!
//! Due to the safety guarantees of Rust, we can automatically memoize components in some circumstances. Whenever a
//! component's properties are valid for the `'static` lifetime, Dioxus will automatically compare the props before
//! diffing the component. If the props don't change (according to PartialEq), the component will not be re-rendered.
//!
//! However, if the props use some generics or borrow from their parent, then Dioxus can't safely supress updates,
//! and is forced to render the child. If you think that this behavior is wrong for your usecase, you can implement
//! the memo method yourself, but beware, doing so is UNSAFE and may cause issues if you do it wrong.
//!
//! If you want to gain that little bit extra performance, consider using global state management, signals, or
//! memoized collections like im-rc which are designed for this use case.
use dioxus::prelude::*;
// By default, components with no props are always memoized.
// A props of () is considered empty.
pub fn Example(cx: Scope) -> Element {
cx.render(rsx! {
div { "100% memoized!" }
})
}
// These props do not borrow any content, and therefore can be safely memoized.
// However, the parent *must* create a new string on every render.
// Notice how these props implement PartialEq - this is required for 'static props
#[derive(PartialEq, Props)]
pub struct MyProps1 {
name: String,
}
pub fn Example1(cx: Scope<MyProps1>) -> Element {
cx.render(rsx! {
div { "100% memoized! {cx.props.name}" }
})
}
// These props do not borrow any content, and therefore can be safely memoized.
// In contrast with the `String` example, these props use `Rc<str>` which operates similar to strings in JavaScript.
// These strings cannot be modified, but may be cheaply shared in many places without issue.
#[derive(PartialEq, Props)]
pub struct MyProps2 {
name: std::rc::Rc<str>,
}
pub fn Example2(cx: Scope<MyProps2>) -> Element {
cx.render(rsx! {
div { "100% memoized! {cx.props.name}" }
})
}
// These props *do* borrow any content, and therefore cannot be safely memoized!.
#[derive(PartialEq, Props)]
pub struct MyProps3<'a> {
name: &'a str,
}
// We need to manually specify a lifetime that ensures props and scope (the component's state) share the same lifetime.
// Using the `pub fn Example(cx: Scope): Component` pattern _will_ specify a lifetime, but that lifetime will be static which might
// not exactly be what you want
fn Example3(cx: Scope<'a, MyProps3<'a>>) -> DomTree {
cx.render(rsx! {
div { "Not memoized! {cx.props.name}" }
})
}
// These props *do* borrow any content, and therefore cannot be safely memoized!.
// However, they cannot be compared, so we don't need the PartialEq flag.
#[derive(Props)]
pub struct MyProps4<'a> {
onhandle: &'a dyn Fn(),
}
// We need to manually specify a lifetime that ensures props and scope (the component's state) share the same lifetime.
fn Example4<'a>(cx: Scope<'a, MyProps4<'a>>) -> DomTree {
cx.render(rsx! {
div { "Not memoized!", onclick: move |_| (props.onhandle)() }
})
}
-41
View File
@@ -1,41 +0,0 @@
//! Example: Spread pattern for Components
//! --------------------------------------
//!
//! Dioxus supports the "spread" pattern for manually building a component's properties. This is useful when props
//! are passed down from a parent, or it's more ergonomic to construct props from outside the rsx! macro.
//!
//! To use the spread pattern, simply pass ".." followed by a Rust expression. This pattern also supports overriding
//! values, using the manual props as the base and then modifying fields specified with non-spread attributes.
use dioxus::prelude::*;
pub fn Example(cx: Scope) -> Element {
let props = MyProps {
count: 0,
live: true,
name: "Dioxus",
};
cx.render(rsx! {
Example1 { ..props, count: 10, div {"child"} }
})
}
#[derive(Props)]
pub struct MyProps<'a> {
count: u32,
live: bool,
name: &'static str,
children: Element<'a>,
}
pub fn Example1<'a>(cx: Scope<'a, MyProps<'a>>) -> Element {
let MyProps { count, live, name } = cx.props;
cx.render(rsx! {
div {
h1 { "Hello, {name}"}
h3 {"Are we alive? {live}"}
p {"Count is {count}"}
&cx.props.children
}
})
}
-38
View File
@@ -1,38 +0,0 @@
//! Example: Suspense
//! -----------------
//! This example demonstrates how the use_suspense hook can be used to load and render asynchronous data. Suspense enables
//! components to wait on futures to complete before rendering the result into VNodes. These VNodes are immediately
//! available in a suspended" fashion and will automatically propagate to the UI when the future completes.
//!
//! Currently, suspense futures are non-restartable. In the future, we'll provide more granular control of how to start,
//! stop, and reset these futures.
use dioxus::prelude::*;
#[derive(serde::Deserialize)]
struct DogApi {
message: String,
}
const ENDPOINT: &str = "https://dog.ceo/api/breeds/image/random";
pub fn Example(cx: Scope) -> Element {
let doggo = use_suspense(
cx,
|| surf::get(ENDPOINT).recv_json::<DogApi>(),
|cx, res| match res {
Ok(res) => rsx!(
cx,
img {
src: "{res.message}"
}
),
Err(_) => rsx!(cx, div { "No doggos for you :(" }),
},
);
cx.render(rsx!(
div {
h1 {"Waiting for a doggo..."}
{doggo}
}
))
}
-61
View File
@@ -1,61 +0,0 @@
//! 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: Component = |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) = use_task(cx, move || async move {
loop {
gloo_timers::future::TimeoutFuture::new(250).await;
*async_count.get_mut() += dir;
}
});
cx.render(rsx! {
div {
h1 {"count is {count}"}
button {
onclick: move |_| task.stop(),
"Stop counting"
}
button {
onclick: move |_| task.resume(),
"Start counting"
}
button {
onclick: move |_| {
direction *= -1;
task.restart();
}
"Switch counting direcion"
}
}
})
};
+2 -1
View File
@@ -2,9 +2,10 @@
Tiny CRM: A port of the Yew CRM example to Dioxus.
*/
use dioxus::prelude::*;
use dioxus_router::{Link, Route, Router};
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
#[derive(Clone, Debug, Default)]
+1 -1
View File
@@ -1,7 +1,7 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+1 -1
View File
@@ -10,7 +10,7 @@ fn main() {
let mut dom = VirtualDom::new(app);
let _ = dom.rebuild();
let output = dioxus::ssr::render_vdom(&dom);
let output = dioxus_ssr::render_vdom(&dom);
println!("{}", output);
}
+2 -2
View File
@@ -4,11 +4,11 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch_cfg(app, |c| {
dioxus_desktop::launch_cfg(app, |c| {
c.with_custom_head("<style>body { background-color: red; }</style>".into())
});
dioxus::desktop::launch_cfg(app, |c| {
dioxus_desktop::launch_cfg(app, |c| {
c.with_custom_index(
r#"
<!DOCTYPE html>
+1 -1
View File
@@ -1,7 +1,7 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+2 -3
View File
@@ -2,12 +2,11 @@
//! Render a bunch of doggos!
use dioxus::prelude::*;
use std::collections::HashMap;
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
#[derive(Debug, Clone, PartialEq, serde::Deserialize)]
+1 -1
View File
@@ -1,7 +1,7 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+2 -3
View File
@@ -1,12 +1,12 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
let script = use_state(&cx, String::new);
let eval = use_eval(&cx);
let eval = dioxus_desktop::use_eval(&cx);
cx.render(rsx! {
div {
@@ -17,7 +17,6 @@ fn app(cx: Scope) -> Element {
}
button {
onclick: move |_| eval(script),
"Execute"
}
}
+2 -1
View File
@@ -1,9 +1,10 @@
#![allow(non_snake_case)]
use dioxus::prelude::*;
use fermi::*;
fn main() {
dioxus::desktop::launch(app)
dioxus_desktop::launch(app)
}
static NAME: Atom<String> = |_| "world".to_string();
+1 -1
View File
@@ -11,7 +11,7 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch_cfg(app, |c| c.with_window(|w| w.with_resizable(true)));
dioxus_desktop::launch_cfg(app, |c| c.with_window(|w| w.with_resizable(true)));
}
fn app(cx: Scope) -> Element {
+1 -1
View File
@@ -1,7 +1,7 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch_with_props(app, (), |c| {
dioxus_desktop::launch_with_props(app, (), |c| {
c.with_file_drop_handler(|_w, e| {
println!("{:?}", e);
true
+3 -2
View File
@@ -1,10 +1,11 @@
use dioxus::desktop::tao::dpi::LogicalSize;
use dioxus::prelude::*;
use dioxus_desktop::tao::dpi::LogicalSize;
use dioxus_router::{Link, Route, Router};
fn main() {
env_logger::init();
dioxus::desktop::launch_cfg(app, |c| {
dioxus_desktop::launch_cfg(app, |c| {
c.with_window(|c| {
c.with_title("Spinsense Client")
.with_inner_size(LogicalSize::new(600, 1000))
+12 -14
View File
@@ -6,24 +6,22 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
cx.render(rsx! {
Router {
div {
h1 { "Form" }
form {
onsubmit: move |ev| println!("Submitted {:?}", ev.values),
oninput: move |ev| println!("Input {:?}", ev.values),
input { r#type: "text", name: "username" }
input { r#type: "text", name: "full-name" }
input { r#type: "password", name: "password" }
input { r#type: "radio", name: "color", value: "red" }
input { r#type: "radio", name: "color", value: "blue" }
button { r#type: "submit", value: "Submit", "Submit the form" }
}
div {
h1 { "Form" }
form {
onsubmit: move |ev| println!("Submitted {:?}", ev.values),
oninput: move |ev| println!("Input {:?}", ev.values),
input { r#type: "text", name: "username" }
input { r#type: "text", name: "full-name" }
input { r#type: "password", name: "password" }
input { r#type: "radio", name: "color", value: "red" }
input { r#type: "radio", name: "color", value: "blue" }
button { r#type: "submit", value: "Submit", "Submit the form" }
}
}
})
+1 -1
View File
@@ -4,7 +4,7 @@ use dioxus::prelude::*;
use rand::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
#[derive(Clone, PartialEq)]
+1 -1
View File
@@ -10,7 +10,7 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+1 -1
View File
@@ -1,7 +1,7 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+2 -3
View File
@@ -10,13 +10,12 @@
//! proof-of-concept for the hydration feature, but you'll probably only want to use hydration for the web.
use dioxus::prelude::*;
use dioxus::ssr;
fn main() {
let vdom = VirtualDom::new(app);
let content = ssr::render_vdom_cfg(&vdom, |f| f.pre_render(true));
let content = dioxus_ssr::render_vdom_cfg(&vdom, |f| f.pre_render(true));
dioxus::desktop::launch_cfg(app, |c| c.with_prerendered(content));
dioxus_desktop::launch_cfg(app, |c| c.with_prerendered(content));
}
fn app(cx: Scope) -> Element {
+1 -1
View File
@@ -24,7 +24,7 @@ fn Thing4<'a>(cx: Scope<'a>, _a: &'a u32) -> Element<'a> {
}
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+1 -1
View File
@@ -5,7 +5,7 @@
use dioxus::{events::FormEvent, prelude::*};
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
const FIELDS: &[(&str, &str)] = &[
+4 -9
View File
@@ -1,25 +1,21 @@
use dioxus::prelude::*;
use dioxus_router::{Link, Route, Router};
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
cx.render(rsx! (
div {
p {
a {
href: "http://dioxuslabs.com/",
"Default link - links outside of your app"
}
a { href: "http://dioxuslabs.com/", "Default link - links outside of your app" }
}
p {
a {
href: "http://dioxuslabs.com/",
prevent_default: "onclick",
onclick: |_| {
println!("Hello Dioxus");
},
onclick: |_| println!("Hello Dioxus"),
"Custom event link - links inside of your app",
}
}
@@ -28,7 +24,6 @@ fn app(cx: Scope) -> Element {
Router {
Route { to: "/", h1 { "Home" } },
Route { to: "/settings", h1 { "settings" } },
p { "----"}
ul {
Link { to: "/", li { "Router link to home" } },
+1 -1
View File
@@ -5,7 +5,7 @@ use dioxus::events::*;
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+1 -1
View File
@@ -7,7 +7,7 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+1 -1
View File
@@ -7,7 +7,7 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+3 -3
View File
@@ -17,13 +17,13 @@
//! the RefCell will panic and crash. You can use `try_get_mut` or `.modify` to avoid this problem, or just not hold two
//! RefMuts at the same time.
use dioxus::desktop::wry::application::dpi::LogicalSize;
use dioxus::events::*;
use dioxus::html::input_data::keyboard_types::Key;
use dioxus::prelude::*;
use dioxus_html::input_data::keyboard_types::Key;
use dioxus_desktop::wry::application::dpi::LogicalSize;
fn main() {
dioxus::desktop::launch_cfg(app, |cfg| {
dioxus_desktop::launch_cfg(app, |cfg| {
cfg.with_window(|w| {
w.with_title("Calculator Demo")
.with_resizable(false)
+1 -1
View File
@@ -11,7 +11,7 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+1 -1
View File
@@ -5,7 +5,7 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+5 -5
View File
@@ -1,11 +1,11 @@
#![allow(non_snake_case)]
use dioxus::prelude::*;
use dioxus::router::{Link, Route, Router};
use dioxus_router::{Link, Route, Router};
use serde::Deserialize;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
@@ -30,7 +30,7 @@ fn app(cx: Scope) -> Element {
}
fn BlogPost(cx: Scope) -> Element {
let post = dioxus::router::use_route(&cx).last_segment()?;
let post = dioxus_router::use_route(&cx).last_segment()?;
cx.render(rsx! {
div {
@@ -46,9 +46,9 @@ struct Query {
}
fn User(cx: Scope) -> Element {
let post = dioxus::router::use_route(&cx).last_segment()?;
let post = dioxus_router::use_route(&cx).last_segment()?;
let query = dioxus::router::use_route(&cx)
let query = dioxus_router::use_route(&cx)
.query::<Query>()
.unwrap_or(Query { bold: false });
+1 -1
View File
@@ -7,7 +7,7 @@ fn main() {
let mut vdom = VirtualDom::new(example);
vdom.rebuild();
let out = dioxus::ssr::render_vdom_cfg(&vdom, |c| c.newline(true).indent(true));
let out = dioxus_ssr::render_vdom_cfg(&vdom, |c| c.newline(true).indent(true));
println!("{}", out);
}
+1 -1
View File
@@ -39,7 +39,7 @@
//! - Allow top-level fragments
//!
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
/// When trying to return "nothing" to Dioxus, you'll need to specify the type parameter or Rust will be sad.
+4 -4
View File
@@ -10,12 +10,12 @@ fn main() {
// We can render VirtualDoms
let mut vdom = VirtualDom::new(app);
let _ = vdom.rebuild();
println!("{}", dioxus::ssr::render_vdom(&vdom));
println!("{}", dioxus_ssr::render_vdom(&vdom));
// Or we can render rsx! calls themselves
println!(
"{}",
dioxus::ssr::render_lazy(rsx! {
dioxus_ssr::render_lazy(rsx! {
div {
h1 { "Hello, world!" }
}
@@ -25,14 +25,14 @@ fn main() {
// We can configure the SSR rendering to add ids for rehydration
println!(
"{}",
dioxus::ssr::render_vdom_cfg(&vdom, |c| c.pre_render(true))
dioxus_ssr::render_vdom_cfg(&vdom, |c| c.pre_render(true))
);
// We can even render as a writer
let mut file = String::new();
let _ = file.write_fmt(format_args!(
"{}",
dioxus::ssr::TextRenderer::from_vdom(&vdom, Default::default())
dioxus_ssr::TextRenderer::from_vdom(&vdom, Default::default())
));
println!("{}", file);
}
+2 -2
View File
@@ -16,8 +16,8 @@
use dioxus::prelude::*;
fn main() {
use dioxus::desktop::tao::dpi::LogicalSize;
dioxus::desktop::launch_cfg(app, |cfg| {
use dioxus_desktop::tao::dpi::LogicalSize;
dioxus_desktop::launch_cfg(app, |cfg| {
cfg.with_window(|w| {
w.with_title("Doggo Fetcher")
.with_inner_size(LogicalSize::new(600.0, 800.0))
+1 -1
View File
@@ -3,7 +3,7 @@
use dioxus::{events::MouseEvent, prelude::*};
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+1 -1
View File
@@ -71,5 +71,5 @@ fn app(cx: Scope) -> Element {
}
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
+1 -1
View File
@@ -11,7 +11,7 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch_cfg(app, |c| {
dioxus_desktop::launch_cfg(app, |c| {
c.with_custom_head("<script src=\"https://cdn.tailwindcss.com\"></script>".to_string())
});
}
+1 -1
View File
@@ -6,7 +6,7 @@ use dioxus::prelude::*;
use std::time::Duration;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+1 -1
View File
@@ -3,7 +3,7 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+1 -1
View File
@@ -2,7 +2,7 @@ use dioxus::prelude::*;
use dioxus_elements::input_data::keyboard_types::Key;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
#[derive(PartialEq)]
-85
View File
@@ -1,85 +0,0 @@
use dioxus::prelude::*;
use dioxus_html::on::{FocusData, KeyboardData, MouseData, WheelData};
use std::sync::Arc;
fn main() {
dioxus::tui::launch(app);
}
#[derive(Debug)]
enum Event {
MouseMove(Arc<MouseData>),
MouseClick(Arc<MouseData>),
MouseDoubleClick(Arc<MouseData>),
MouseDown(Arc<MouseData>),
MouseUp(Arc<MouseData>),
Wheel(Arc<WheelData>),
KeyDown(Arc<KeyboardData>),
KeyUp(Arc<KeyboardData>),
KeyPress(Arc<KeyboardData>),
FocusIn(Arc<FocusData>),
FocusOut(Arc<FocusData>),
}
const MAX_EVENTS: usize = 8;
fn app(cx: Scope) -> Element {
let events = use_ref(&cx, Vec::new);
let events_lock = events.read();
let first_index = events_lock.len().saturating_sub(MAX_EVENTS);
let events_rendered = events_lock[first_index..].iter().map(|event| {
// TUI panics if text overflows (https://github.com/DioxusLabs/dioxus/issues/371)
// temporary hack: just trim the strings (and make sure viewport is big enough)
// todo: remove
let mut trimmed = format!("{event:?}");
trimmed.truncate(200);
cx.render(rsx!(p { "{trimmed}" }))
});
let log_event = move |event: Event| {
events.write().push(event);
};
cx.render(rsx! {
div {
width: "100%",
height: "100%",
flex_direction: "column",
div {
width: "80%",
height: "50%",
border_width: "1px",
justify_content: "center",
align_items: "center",
background_color: "hsl(248, 53%, 58%)",
onmousemove: move |event| log_event(Event::MouseMove(event.data)),
onclick: move |event| log_event(Event::MouseClick(event.data)),
ondblclick: move |event| log_event(Event::MouseDoubleClick(event.data)),
onmousedown: move |event| log_event(Event::MouseDown(event.data)),
onmouseup: move |event| log_event(Event::MouseUp(event.data)),
onwheel: move |event| log_event(Event::Wheel(event.data)),
onkeydown: move |event| log_event(Event::KeyDown(event.data)),
onkeyup: move |event| log_event(Event::KeyUp(event.data)),
onkeypress: move |event| log_event(Event::KeyPress(event.data)),
onfocusin: move |event| log_event(Event::FocusIn(event.data)),
onfocusout: move |event| log_event(Event::FocusOut(event.data)),
"Hover, click, type or scroll to see the info down below"
},
div {
width: "80%",
height: "50%",
flex_direction: "column",
events_rendered,
},
},
})
}
-27
View File
@@ -1,27 +0,0 @@
use dioxus::prelude::*;
fn main() {
dioxus::tui::launch(app);
}
fn app(cx: Scope) -> Element {
let radius = use_state(&cx, || 0);
cx.render(rsx! {
div {
width: "100%",
height: "100%",
justify_content: "center",
align_items: "center",
background_color: "hsl(248, 53%, 58%)",
onwheel: move |w| radius.modify(|r| (r + w.delta().strip_units().y as i8).abs()),
border_style: "solid none solid double",
border_width: "thick",
border_radius: "{radius}px",
border_color: "#0000FF #FF00FF #FF0000 #00FF00",
"{radius}"
}
})
}
-94
View File
@@ -1,94 +0,0 @@
use dioxus::prelude::*;
use dioxus_html::input_data::keyboard_types::Code;
fn main() {
dioxus::tui::launch(app);
}
#[derive(PartialEq, Props)]
struct ButtonProps {
color_offset: u32,
layer: u16,
}
#[allow(non_snake_case)]
fn Button(cx: Scope<ButtonProps>) -> Element {
let toggle = use_state(&cx, || false);
let hovered = use_state(&cx, || false);
let hue = cx.props.color_offset % 255;
let saturation = if *toggle.get() { 50 } else { 25 } + if *hovered.get() { 50 } else { 25 };
let brightness = saturation / 2;
let color = format!("hsl({hue}, {saturation}, {brightness})");
cx.render(rsx! {
div{
width: "100%",
height: "100%",
background_color: "{color}",
tabindex: "{cx.props.layer}",
onkeydown: |e| {
if let Code::Space = e.data.code() {
toggle.modify(|f| !f);
}
},
onclick: |_| {
toggle.modify(|f| !f);
},
onmouseenter: |_|{
hovered.set(true);
},
onmouseleave: |_|{
hovered.set(false);
},
justify_content: "center",
align_items: "center",
display: "flex",
flex_direction: "column",
p{"tabindex: {cx.props.layer}"}
}
})
}
fn app(cx: Scope) -> Element {
cx.render(rsx! {
div {
display: "flex",
flex_direction: "column",
width: "100%",
height: "100%",
(1..8).map(|y|
cx.render(rsx!{
div{
display: "flex",
flex_direction: "row",
width: "100%",
height: "100%",
(1..8).map(|x|{
if (x + y) % 2 == 0{
cx.render(rsx!{
div{
width: "100%",
height: "100%",
background_color: "rgb(100, 100, 100)",
}
})
}
else{
let layer = (x + y) % 3;
cx.render(rsx!{
Button{
color_offset: x * y,
layer: layer as u16,
}
})
}
})
}
})
)
}
})
}
-45
View File
@@ -1,45 +0,0 @@
use dioxus::prelude::*;
fn main() {
dioxus::tui::launch_cfg(
app,
dioxus::tui::Config::default().with_rendering_mode(dioxus::tui::RenderingMode::Ansi),
);
}
fn app(cx: Scope) -> Element {
let steps = 50;
cx.render(rsx! {
div{
width: "100%",
height: "100%",
flex_direction: "column",
(0..=steps).map(|x|
{
let hue = x as f32*360.0/steps as f32;
cx.render(rsx! {
div{
width: "100%",
height: "100%",
flex_direction: "row",
(0..=steps).map(|y|
{
let alpha = y as f32*100.0/steps as f32;
cx.render(rsx! {
div {
left: "{x}px",
top: "{y}px",
width: "10%",
height: "100%",
background_color: "hsl({hue}, 100%, 50%, {alpha}%)",
}
})
}
)
}
})
}
)
}
})
}
-27
View File
@@ -1,27 +0,0 @@
use dioxus::prelude::*;
use dioxus_tui::query::Query;
use dioxus_tui::Size;
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);
let tui_query: Query = cx.consume_context().unwrap();
cx.render(rsx! {
div{
width: "100%",
background_color: "hsl({hue}, 70%, {brightness}%)",
onmousemove: move |evt| {
let node = tui_query.get(cx.root_node().mounted_id());
let Size{width, height} = node.size().unwrap();
let pos = evt.data.element_coordinates();
hue.set((pos.x as f32/width as f32)*255.0);
brightness.set((pos.y as f32/height as f32)*100.0);
},
"hsl({hue}, 70%, {brightness}%)",
}
})
}
-66
View File
@@ -1,66 +0,0 @@
#![allow(non_snake_case)]
use dioxus::prelude::*;
fn main() {
dioxus::tui::launch(app);
}
#[derive(Props, PartialEq)]
struct QuadrentProps {
color: String,
text: String,
}
fn Quadrant(cx: Scope<QuadrentProps>) -> Element {
cx.render(rsx! {
div {
border_width: "1px",
width: "50%",
height: "100%",
background_color: "{cx.props.color}",
justify_content: "center",
align_items: "center",
"{cx.props.text}"
}
})
}
fn app(cx: Scope) -> Element {
cx.render(rsx! {
div {
width: "100%",
height: "100%",
flex_direction: "column",
div {
width: "100%",
height: "50%",
flex_direction: "row",
Quadrant{
color: "red".to_string(),
text: "[A]".to_string()
},
Quadrant{
color: "black".to_string(),
text: "[B]".to_string()
}
}
div {
width: "100%",
height: "50%",
flex_direction: "row",
Quadrant{
color: "green".to_string(),
text: "[C]".to_string()
},
Quadrant{
color: "blue".to_string(),
text: "[D]".to_string()
}
}
}
})
}
-82
View File
@@ -1,82 +0,0 @@
use dioxus::prelude::*;
fn main() {
dioxus::tui::launch(app);
}
fn app(cx: Scope) -> Element {
cx.render(rsx! {
div {
width: "100%",
height: "100%",
flex_direction: "column",
// justify_content: "center",
// align_items: "center",
// flex_direction: "row",
// background_color: "red",
p {
background_color: "black",
flex_direction: "column",
justify_content: "center",
align_items: "center",
// height: "10%",
"hi"
"hi"
"hi"
}
li {
background_color: "red",
flex_direction: "column",
justify_content: "center",
align_items: "center",
// height: "10%",
"bib"
"bib"
"bib"
"bib"
"bib"
"bib"
"bib"
"bib"
}
li {
background_color: "blue",
flex_direction: "column",
justify_content: "center",
align_items: "center",
// height: "10%",
"zib"
"zib"
"zib"
"zib"
"zib"
"zib"
"zib"
"zib"
"zib"
"zib"
"zib"
"zib"
"zib"
}
p {
background_color: "yellow",
"asd"
}
p {
background_color: "green",
"asd"
}
p {
background_color: "white",
"asd"
}
p {
background_color: "cyan",
"asd"
}
}
})
}
-128
View File
@@ -1,128 +0,0 @@
use std::{convert::TryInto, sync::Arc};
use dioxus::{events::MouseData, prelude::*};
use dioxus_core::UiEvent;
fn main() {
dioxus::tui::launch(app);
}
fn app(cx: Scope) -> Element {
fn to_str(c: &[i32; 3]) -> String {
"#".to_string() + &c.iter().map(|c| format!("{c:02X?}")).collect::<String>()
}
fn get_brightness(m: Arc<MouseData>) -> i32 {
let b: i32 = m.held_buttons().len().try_into().unwrap();
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_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 update_data = move |event: UiEvent<MouseData>| {
let mouse_data = event.data;
page_coordinates.set(format!("{:?}", mouse_data.page_coordinates()));
element_coordinates.set(format!("{:?}", mouse_data.element_coordinates()));
// Note: client coordinates are also available, but they would be the same as the page coordinates in this example, because there is no scrolling.
// There are also screen coordinates, but they are currently the same as client coordinates due to technical limitations
buttons.set(format!("{:?}", mouse_data.held_buttons()));
modifiers.set(format!("{:?}", mouse_data.modifiers()));
};
cx.render(rsx! {
div {
width: "100%",
height: "100%",
flex_direction: "column",
div {
width: "100%",
height: "50%",
flex_direction: "row",
div {
border_width: "1px",
width: "50%",
height: "100%",
justify_content: "center",
align_items: "center",
background_color: "{q1_color_str}",
onmouseenter: move |m| q1_color.set([get_brightness(m.data), 0, 0]),
onmousedown: move |m| q1_color.set([get_brightness(m.data), 0, 0]),
onmouseup: move |m| q1_color.set([get_brightness(m.data), 0, 0]),
onwheel: move |w| q1_color.set([q1_color[0] + (10.0*w.delta().strip_units().y) as i32, 0, 0]),
onmouseleave: move |_| q1_color.set([200; 3]),
onmousemove: update_data,
"click me"
}
div {
width: "50%",
height: "100%",
justify_content: "center",
align_items: "center",
background_color: "{q2_color_str}",
onmouseenter: move |m| q2_color.set([get_brightness(m.data); 3]),
onmousedown: move |m| q2_color.set([get_brightness(m.data); 3]),
onmouseup: move |m| q2_color.set([get_brightness(m.data); 3]),
onwheel: move |w| q2_color.set([q2_color[0] + (10.0*w.delta().strip_units().y) as i32;3]),
onmouseleave: move |_| q2_color.set([200; 3]),
onmousemove: update_data,
"click me"
}
}
div {
width: "100%",
height: "50%",
flex_direction: "row",
div {
width: "50%",
height: "100%",
justify_content: "center",
align_items: "center",
background_color: "{q3_color_str}",
onmouseenter: move |m| q3_color.set([0, get_brightness(m.data), 0]),
onmousedown: move |m| q3_color.set([0, get_brightness(m.data), 0]),
onmouseup: move |m| q3_color.set([0, get_brightness(m.data), 0]),
onwheel: move |w| q3_color.set([0, q3_color[1] + (10.0*w.delta().strip_units().y) as i32, 0]),
onmouseleave: move |_| q3_color.set([200; 3]),
onmousemove: update_data,
"click me"
}
div {
width: "50%",
height: "100%",
justify_content: "center",
align_items: "center",
background_color: "{q4_color_str}",
onmouseenter: move |m| q4_color.set([0, 0, get_brightness(m.data)]),
onmousedown: move |m| q4_color.set([0, 0, get_brightness(m.data)]),
onmouseup: move |m| q4_color.set([0, 0, get_brightness(m.data)]),
onwheel: move |w| q4_color.set([0, 0, q4_color[2] + (10.0*w.delta().strip_units().y) as i32]),
onmouseleave: move |_| q4_color.set([200; 3]),
onmousemove: update_data,
"click me"
}
},
div {"Page coordinates: {page_coordinates}"},
div {"Element coordinates: {element_coordinates}"},
div {"Buttons: {buttons}"},
div {"Modifiers: {modifiers}"},
}
})
}
-66
View File
@@ -1,66 +0,0 @@
use dioxus::events::WheelEvent;
use dioxus::prelude::*;
use dioxus_html::geometry::ScreenPoint;
use dioxus_html::input_data::keyboard_types::Code;
use dioxus_html::input_data::MouseButtonSet;
use dioxus_html::on::{KeyboardEvent, MouseEvent};
fn main() {
dioxus::tui::launch(app);
}
fn app(cx: Scope) -> Element {
let key = use_state(&cx, || "".to_string());
let mouse = use_state(&cx, ScreenPoint::zero);
let count = use_state(&cx, || 0);
let buttons = use_state(&cx, MouseButtonSet::empty);
let mouse_clicked = use_state(&cx, || false);
let key_down_handler = move |evt: KeyboardEvent| {
match evt.data.code() {
Code::ArrowLeft => count.set(count + 1),
Code::ArrowRight => count.set(count - 1),
Code::ArrowUp => count.set(count + 10),
Code::ArrowDown => count.set(count - 10),
_ => {}
}
key.set(format!(
"{:?} repeating: {:?}",
evt.key(),
evt.is_auto_repeating()
));
};
cx.render(rsx! {
div {
width: "100%",
height: "10px",
background_color: "red",
justify_content: "center",
align_items: "center",
flex_direction: "column",
onkeydown: key_down_handler,
onwheel: move |evt: WheelEvent| {
count.set(count + evt.data.delta().strip_units().y as i64);
},
ondrag: move |evt: MouseEvent| {
mouse.set(evt.data.screen_coordinates());
},
onmousedown: move |evt: MouseEvent| {
mouse.set(evt.data.screen_coordinates());
buttons.set(evt.data.held_buttons());
mouse_clicked.set(true);
},
onmouseup: move |evt: MouseEvent| {
buttons.set(evt.data.held_buttons());
mouse_clicked.set(false);
},
"count: {count:?}",
"key: {key}",
"mouse buttons: {buttons:?}",
"mouse pos: {mouse:?}",
"mouse button pressed: {mouse_clicked}"
}
})
}
-28
View File
@@ -1,28 +0,0 @@
use dioxus::prelude::*;
fn main() {
dioxus::tui::launch(app);
}
fn app(cx: Scope) -> Element {
cx.render(rsx! {
div {
width: "100%",
height: "100%",
flex_direction: "column",
border_width: "1px",
h1 { height: "2px", color: "green",
"that's awesome!"
}
ul {
flex_direction: "column",
padding_left: "3px",
(0..10).map(|i| rsx!(
"> hello {i}"
))
}
}
})
}
-50
View File
@@ -1,50 +0,0 @@
use dioxus::prelude::*;
fn main() {
dioxus::tui::launch(app);
}
fn app(cx: Scope) -> Element {
cx.render(rsx! {
div {
width: "100%",
height: "100%",
flex_direction: "column",
background_color: "black",
// margin_right: "10px",
div {
width: "70%",
height: "70%",
background_color: "green",
// margin_left: "4px",
div {
width: "100%",
height: "100%",
margin_top: "2px",
margin_bottom: "2px",
margin_left: "2px",
margin_right: "2px",
flex_shrink: "0",
background_color: "red",
justify_content: "center",
align_items: "center",
flex_direction: "column",
// padding_top: "2px",
// padding_bottom: "2px",
// padding_left: "4px",
// padding_right: "4px",
"[A]"
"[A]"
"[A]"
"[A]"
}
}
}
})
}
-60
View File
@@ -1,60 +0,0 @@
use dioxus::prelude::*;
fn main() {
dioxus::tui::launch(app);
}
fn app(cx: Scope) -> Element {
cx.render(rsx! {
div {
width: "100%",
height: "100%",
flex_direction: "column",
div {
width: "100%",
height: "50%",
flex_direction: "row",
div {
border_width: "1px",
width: "50%",
height: "100%",
background_color: "red",
justify_content: "center",
align_items: "center",
"[A]"
}
div {
width: "50%",
height: "100%",
background_color: "black",
justify_content: "center",
align_items: "center",
"[B]"
}
}
div {
width: "100%",
height: "50%",
flex_direction: "row",
div {
width: "50%",
height: "100%",
background_color: "green",
justify_content: "center",
align_items: "center",
"[C]"
}
div {
width: "50%",
height: "100%",
background_color: "blue",
justify_content: "center",
align_items: "center",
"[D]"
}
}
}
})
}
-19
View File
@@ -1,19 +0,0 @@
use dioxus::prelude::*;
fn main() {
dioxus::tui::launch(app);
}
fn app(cx: Scope) -> Element {
cx.render(rsx! {
div {
width: "100%",
height: "10px",
background_color: "red",
justify_content: "center",
align_items: "center",
"Hello world!"
}
})
}
-32
View File
@@ -1,32 +0,0 @@
use dioxus::prelude::*;
fn main() {
dioxus::tui::launch(app);
}
fn app(cx: Scope) -> Element {
let count = use_state(&cx, || 0);
use_future(&cx, (), move |_| {
let count = count.to_owned();
let update = cx.schedule_update();
async move {
loop {
count.with_mut(|f| *f += 1);
tokio::time::sleep(std::time::Duration::from_millis(1000)).await;
update();
}
}
});
cx.render(rsx! {
div { width: "100%",
div { width: "50%", height: "5px", background_color: "blue", justify_content: "center", align_items: "center",
"Hello {count}!"
}
div { width: "50%", height: "10px", background_color: "red", justify_content: "center", align_items: "center",
"Hello {count}!"
}
}
})
}
-113
View File
@@ -1,113 +0,0 @@
use dioxus::prelude::*;
fn main() {
dioxus::tui::launch(app);
}
fn app(cx: Scope) -> Element {
let alpha = use_state(&cx, || 100);
cx.render(rsx! {
div {
width: "100%",
height: "100%",
flex_direction: "column",
onwheel: move |evt| alpha.set((**alpha + evt.data.delta().strip_units().y as i64).min(100).max(0)),
p {
background_color: "black",
flex_direction: "column",
justify_content: "center",
align_items: "center",
color: "green",
"hi"
"hi"
"hi"
}
li {
background_color: "red",
flex_direction: "column",
justify_content: "center",
align_items: "center",
"bib"
"bib"
"bib"
"bib"
"bib"
"bib"
"bib"
"bib"
}
li {
background_color: "blue",
flex_direction: "column",
justify_content: "center",
align_items: "center",
"zib"
"zib"
"zib"
"zib"
"zib"
"zib"
}
p {
background_color: "yellow",
"asd"
}
p {
background_color: "green",
"asd"
}
p {
background_color: "white",
"asd"
}
p {
background_color: "cyan",
"asd"
}
div {
font_weight: "bold",
color: "#666666",
p {
"bold"
}
p {
font_weight: "normal",
" normal"
}
}
p {
font_style: "italic",
color: "red",
"italic"
}
p {
text_decoration: "underline",
color: "rgba(255, 255, 255)",
"underline"
}
p {
text_decoration: "line-through",
color: "hsla(10, 100%, 70%)",
"line-through"
}
div{
position: "absolute",
top: "1px",
background_color: "rgba(255, 0, 0, 50%)",
width: "100%",
p {
color: "rgba(255, 255, 255, {alpha}%)",
background_color: "rgba(100, 100, 100, {alpha}%)",
"rgba(255, 255, 255, {alpha}%)"
}
p {
color: "rgba(255, 255, 255, 100%)",
"rgba(255, 255, 255, 100%)"
}
}
}
})
}
+2 -2
View File
@@ -1,13 +1,13 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch_cfg(app, |cfg| {
dioxus_desktop::launch_cfg(app, |cfg| {
cfg.with_window(|w| w.with_title("BorderLess Demo").with_decorations(false))
});
}
fn app(cx: Scope) -> Element {
let window = dioxus::desktop::use_window(&cx);
let window = dioxus_desktop::use_window(&cx);
// if you want to make window fullscreen, you need close the resizable.
// window.set_fullscreen(true);
+2 -2
View File
@@ -1,8 +1,8 @@
use dioxus::desktop::use_window;
use dioxus::prelude::*;
use dioxus_desktop::use_window;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {
+1 -1
View File
@@ -5,7 +5,7 @@
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
dioxus_desktop::launch(app);
}
fn app(cx: Scope) -> Element {