Clean up a number of examples
This commit is contained in:
30 files changed
+284
-413
No files matched your search
+10
-10
@@ -26,15 +26,15 @@ fn app() -> Element {
|
||||
val.set(String::new());
|
||||
}
|
||||
|
||||
val.make_mut().push_str(num.to_string().as_str());
|
||||
val.write().push_str(num.to_string().as_str());
|
||||
};
|
||||
|
||||
let input_operator = move |key: &str| val.make_mut().push_str(key);
|
||||
let input_operator = move |key: &str| val.write().push_str(key);
|
||||
|
||||
let handle_key_down_event = move |evt: KeyboardEvent| match evt.key() {
|
||||
Key::Backspace => {
|
||||
if !val.len() != 0 {
|
||||
val.make_mut().pop();
|
||||
if !val().is_empty() {
|
||||
val.write().pop();
|
||||
}
|
||||
}
|
||||
Key::Character(character) => match character.as_str() {
|
||||
@@ -72,16 +72,16 @@ fn app() -> Element {
|
||||
class: "calculator-key key-clear",
|
||||
onclick: move |_| {
|
||||
val.set(String::new());
|
||||
if !val.is_empty(){
|
||||
if !val().is_empty(){
|
||||
val.set("0".into());
|
||||
}
|
||||
},
|
||||
if val.is_empty() { "C" } else { "AC" }
|
||||
if val().is_empty() { "C" } else { "AC" }
|
||||
}
|
||||
button {
|
||||
class: "calculator-key key-sign",
|
||||
onclick: move |_| {
|
||||
let temp = calc_val(val.as_str());
|
||||
let temp = calc_val(val().as_str());
|
||||
if temp > 0.0 {
|
||||
val.set(format!("-{temp}"));
|
||||
} else {
|
||||
@@ -94,7 +94,7 @@ fn app() -> Element {
|
||||
class: "calculator-key key-percent",
|
||||
onclick: move |_| {
|
||||
val.set(
|
||||
format!("{}", calc_val(val.as_str()) / 100.0)
|
||||
format!("{}", calc_val(val().as_str()) / 100.0)
|
||||
);
|
||||
},
|
||||
"%"
|
||||
@@ -102,7 +102,7 @@ fn app() -> Element {
|
||||
}
|
||||
div { class: "digit-keys",
|
||||
button { class: "calculator-key key-0", onclick: move |_| input_digit(0), "0" }
|
||||
button { class: "calculator-key key-dot", onclick: move |_| val.make_mut().push('.'), "●" }
|
||||
button { class: "calculator-key key-dot", onclick: move |_| val.write().push('.'), "●" }
|
||||
for k in 1..10 {
|
||||
button {
|
||||
class: "calculator-key {k}",
|
||||
@@ -120,7 +120,7 @@ fn app() -> Element {
|
||||
button { class: "calculator-key key-add", onclick: move |_| input_operator("+"), "+" }
|
||||
button {
|
||||
class: "calculator-key key-equals",
|
||||
onclick: move |_| val.set(format!("{}", calc_val(val.as_str()))),
|
||||
onclick: move |_| val.set(format!("{}", calc_val(val().as_str()))),
|
||||
"="
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ fn app() -> Element {
|
||||
let elements = use_signal(Vec::<Rc<MountedData>>::new);
|
||||
let running = use_signal(|| true);
|
||||
|
||||
use_future(|| async move {
|
||||
use_future(move || async move {
|
||||
let mut focused = 0;
|
||||
if *running.current() {
|
||||
if *running() {
|
||||
loop {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
|
||||
if let Some(element) = elements.with(|f| f.get(focused).cloned()) {
|
||||
|
||||
+6
-6
@@ -13,22 +13,22 @@ fn app() -> Element {
|
||||
|
||||
render! {
|
||||
div {
|
||||
button { onclick: move |_| counters.make_mut().push(0), "Add counter" }
|
||||
button { onclick: move |_| { counters.make_mut().pop(); }, "Remove counter" }
|
||||
button { onclick: move |_| counters.write().push(0), "Add counter" }
|
||||
button { onclick: move |_| { counters.write().pop(); }, "Remove counter" }
|
||||
p { "Total: {sum}" }
|
||||
for (i, counter) in counters.iter().enumerate() {
|
||||
li {
|
||||
button { onclick: move |_| counters.make_mut()[i] -= 1, "-1" }
|
||||
button { onclick: move |_| counters.write()[i] -= 1, "-1" }
|
||||
input {
|
||||
value: "{counter}",
|
||||
oninput: move |e| {
|
||||
if let Ok(value) = e.value().parse::<usize>() {
|
||||
counters.make_mut()[i] = value;
|
||||
counters.write()[i] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
button { onclick: move |_| counters.make_mut()[i] += 1, "+1" }
|
||||
button { onclick: move |_| { counters.make_mut().remove(i); }, "x" }
|
||||
button { onclick: move |_| counters.write()[i] += 1, "+1" }
|
||||
button { onclick: move |_| { counters.write().remove(i); }, "x" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-9
@@ -27,7 +27,7 @@ pub struct Client {
|
||||
type ClientContext = Vec<Client>;
|
||||
|
||||
#[component]
|
||||
fn App(props: ()) -> Element {
|
||||
fn App() -> Element {
|
||||
use_shared_state_provider::<ClientContext>(Default::default);
|
||||
|
||||
render! {
|
||||
@@ -58,15 +58,10 @@ fn ClientList() -> Element {
|
||||
|
||||
rsx! {
|
||||
h2 { "List of Clients" }
|
||||
|
||||
Link { to: Route::ClientAdd {}, class: "pure-button pure-button-primary", "Add Client" }
|
||||
Link { to: Route::Settings {}, class: "pure-button", "Settings" }
|
||||
|
||||
for client in clients.read().iter() {
|
||||
div {
|
||||
class: "client",
|
||||
style: "margin-bottom: 50px",
|
||||
|
||||
div { class: "client", style: "margin-bottom: 50px",
|
||||
p { "Name: {client.first_name} {client.last_name}" }
|
||||
p { "Description: {client.description}" }
|
||||
}
|
||||
@@ -75,7 +70,7 @@ fn ClientList() -> Element {
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn ClientAdd(props: ()) -> Element {
|
||||
fn ClientAdd() -> Element {
|
||||
let clients = use_shared_state::<ClientContext>().unwrap();
|
||||
let first_name = use_signal(String::new);
|
||||
let last_name = use_signal(String::new);
|
||||
@@ -142,7 +137,7 @@ fn ClientAdd(props: ()) -> Element {
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Settings(props: ()) -> Element {
|
||||
fn Settings() -> Element {
|
||||
let clients = use_shared_state::<ClientContext>().unwrap();
|
||||
|
||||
rsx! {
|
||||
|
||||
@@ -9,17 +9,13 @@ fn app() -> Element {
|
||||
|
||||
rsx! {
|
||||
div {
|
||||
button {
|
||||
onclick: move |_| disabled.set(!disabled),
|
||||
button { onclick: move |_| disabled.toggle(),
|
||||
"click to "
|
||||
if disabled == true { "enable" } else { "disable" }
|
||||
if *disabled() { "enable" } else { "disable" }
|
||||
" the lower button"
|
||||
}
|
||||
|
||||
button {
|
||||
disabled: "{disabled}",
|
||||
"lower button"
|
||||
}
|
||||
button { disabled, "lower button" }
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -2,7 +2,7 @@ use dioxus::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn main() {
|
||||
dioxus_desktop::launch(|cx| render!(AppRoot {}));
|
||||
dioxus_desktop::launch(app);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, serde::Deserialize)]
|
||||
@@ -10,8 +10,7 @@ struct ListBreeds {
|
||||
message: HashMap<String, Vec<String>>,
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn AppRoot(_: ()) -> Element {
|
||||
fn app() -> Element {
|
||||
let breed = use_signal(|| "deerhound".to_string());
|
||||
|
||||
let breeds = use_future(|| async move {
|
||||
|
||||
@@ -4,8 +4,7 @@ fn main() {
|
||||
dioxus_desktop::launch(App);
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn App(_: ()) -> Element {
|
||||
fn app() -> Element {
|
||||
rsx! {
|
||||
ErrorBoundary {
|
||||
handle_error: |error: CapturedError| rsx! {"Found error {error}"},
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use dioxus::prelude::*;
|
||||
use fermi::*;
|
||||
|
||||
fn main() {
|
||||
dioxus_desktop::launch(app)
|
||||
}
|
||||
|
||||
static NAME: Atom<String> = Atom(|_| "world".to_string());
|
||||
|
||||
fn app() -> Element {
|
||||
use_init_atom_root(cx);
|
||||
let name = use_read(&NAME);
|
||||
|
||||
rsx! {
|
||||
div { "hello {name}!" }
|
||||
Child {}
|
||||
ChildWithRef {}
|
||||
}
|
||||
}
|
||||
|
||||
fn Child() -> Element {
|
||||
let set_name = use_set(&NAME);
|
||||
|
||||
rsx! {
|
||||
button {
|
||||
onclick: move |_| set_name("dioxus".to_string()),
|
||||
"reset name"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static NAMES: AtomRef<Vec<String>> = AtomRef(|_| vec!["world".to_string()]);
|
||||
|
||||
fn ChildWithRef() -> Element {
|
||||
let names = use_atom_ref(&NAMES);
|
||||
|
||||
rsx! {
|
||||
div {
|
||||
ul {
|
||||
for name in names.read().iter() {
|
||||
li { "hello: {name}" }
|
||||
}
|
||||
}
|
||||
button {
|
||||
onclick: move |_| {
|
||||
let names = names.clone();
|
||||
cx.spawn(async move {
|
||||
names.write().push("asd".to_string());
|
||||
})
|
||||
},
|
||||
"Add name"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,20 +12,19 @@ use dioxus::prelude::*;
|
||||
use dioxus_desktop::{Config, WindowBuilder};
|
||||
|
||||
fn main() {
|
||||
dioxus_desktop::launch_cfg(
|
||||
app,
|
||||
Config::new().with_window(WindowBuilder::new().with_resizable(true)),
|
||||
);
|
||||
Config::new()
|
||||
.with_window(WindowBuilder::new().with_resizable(true))
|
||||
.launch(app)
|
||||
}
|
||||
|
||||
const _STYLE: &str = manganis::mg!(file("./examples/assets/fileexplorer.css"));
|
||||
|
||||
fn app() -> Element {
|
||||
fn app(_props: ()) -> Element {
|
||||
let files = use_signal(Files::new);
|
||||
|
||||
rsx! {
|
||||
div {
|
||||
link { href:"https://fonts.googleapis.com/icon?family=Material+Icons", rel:"stylesheet", }
|
||||
link { href:"https://fonts.googleapis.com/icon?family=Material+Icons", rel:"stylesheet" }
|
||||
header {
|
||||
i { class: "material-icons icon-menu", "menu" }
|
||||
h1 { "Files: ", {files.read().current()} }
|
||||
|
||||
+26
-34
@@ -9,16 +9,33 @@ fn main() {
|
||||
|
||||
fn App() -> Element {
|
||||
let enable_directory_upload = use_signal(|| false);
|
||||
let files_uploaded: Signal<Vec<String>> = use_signal(Vec::new);
|
||||
let files_uploaded = use_signal(|| Vec::new() as Vec<String>);
|
||||
|
||||
let upload_files = move |evt: FormEvent| async move {
|
||||
for file_name in evt.files().unwrap().files() {
|
||||
// no files on form inputs?
|
||||
sleep(std::time::Duration::from_secs(1)).await;
|
||||
files_uploaded.write().push(file_name);
|
||||
}
|
||||
};
|
||||
|
||||
let handle_file_drop = move |evt: DragEvent| async move {
|
||||
if let Some(file_engine) = &evt.files() {
|
||||
let files = file_engine.files();
|
||||
for file_name in &files {
|
||||
if let Some(file) = file_engine.read_file_to_string(file_name).await {
|
||||
files_uploaded.write().push(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
rsx! {
|
||||
label {
|
||||
input {
|
||||
r#type: "checkbox",
|
||||
checked: "{enable_directory_upload}",
|
||||
oninput: move |evt| {
|
||||
enable_directory_upload.set(evt.value().parse().unwrap());
|
||||
},
|
||||
checked: enable_directory_upload,
|
||||
oninput: move |evt| enable_directory_upload.set(evt.value().parse().unwrap()),
|
||||
},
|
||||
"Enable directory upload"
|
||||
}
|
||||
@@ -27,41 +44,16 @@ fn App() -> Element {
|
||||
r#type: "file",
|
||||
accept: ".txt,.rs",
|
||||
multiple: true,
|
||||
directory: **enable_directory_upload,
|
||||
onchange: |evt| {
|
||||
to_owned![files_uploaded];
|
||||
async move {
|
||||
if let Some(file_engine) = &evt.files() {
|
||||
let files = file_engine.files();
|
||||
for file_name in files {
|
||||
sleep(std::time::Duration::from_secs(1)).await;
|
||||
files_uploaded.write().push(file_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
directory: enable_directory_upload,
|
||||
onchange: upload_files,
|
||||
}
|
||||
div {
|
||||
width: "100px",
|
||||
height: "100px",
|
||||
border: "1px solid black",
|
||||
prevent_default: "ondrop dragover dragenter",
|
||||
ondrop: move |evt| {
|
||||
to_owned![files_uploaded];
|
||||
async move {
|
||||
if let Some(file_engine) = &evt.files() {
|
||||
let files = file_engine.files();
|
||||
for file_name in &files {
|
||||
if let Some(file) = file_engine.read_file_to_string(file_name).await{
|
||||
files_uploaded.write().push(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
ondragover: move |event: DragEvent| {
|
||||
event.stop_propagation();
|
||||
},
|
||||
ondrop: handle_file_drop,
|
||||
ondragover: move |event| event.stop_propagation(),
|
||||
"Drop files here"
|
||||
}
|
||||
|
||||
|
||||
@@ -2,15 +2,15 @@ use dioxus::prelude::*;
|
||||
use dioxus_desktop::Config;
|
||||
|
||||
fn main() {
|
||||
let cfg = Config::new().with_file_drop_handler(|_w, e| {
|
||||
println!("{e:?}");
|
||||
true
|
||||
});
|
||||
|
||||
dioxus_desktop::launch_with_props(app, (), cfg);
|
||||
Config::new()
|
||||
.with_file_drop_handler(|_w, e| {
|
||||
println!("{e:?}");
|
||||
true
|
||||
})
|
||||
.launch(app)
|
||||
}
|
||||
|
||||
fn app() -> Element {
|
||||
fn app(_props: ()) -> Element {
|
||||
rsx!(
|
||||
div {
|
||||
h1 { "drag a file here and check your console" }
|
||||
|
||||
+11
-14
@@ -5,20 +5,17 @@ use dioxus_router::prelude::*;
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let cfg = Config::new().with_window(
|
||||
WindowBuilder::new()
|
||||
.with_inner_size(LogicalSize::new(600, 1000))
|
||||
.with_resizable(false),
|
||||
);
|
||||
|
||||
dioxus_desktop::launch_cfg(App, cfg)
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn App() -> Element {
|
||||
render! {
|
||||
Router::<Route> {}
|
||||
}
|
||||
Config::new()
|
||||
.with_window(
|
||||
WindowBuilder::new()
|
||||
.with_inner_size(LogicalSize::new(600, 1000))
|
||||
.with_resizable(false),
|
||||
)
|
||||
.launch(|| {
|
||||
render! {
|
||||
Router::<Route> {}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[derive(Routable, Clone)]
|
||||
|
||||
@@ -12,13 +12,13 @@ fn app() -> Element {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Props)]
|
||||
struct GenericChildProps<T: Display + PartialEq> {
|
||||
#[derive(PartialEq, Props, Clone)]
|
||||
struct GenericChildProps<T: Display + PartialEq + Clone + 'static> {
|
||||
data: T,
|
||||
}
|
||||
|
||||
fn generic_child<T: Display + PartialEq>(cx: Scope<GenericChildProps<T>>) -> Element {
|
||||
fn generic_child<T: Display + PartialEq + Clone>(props: GenericChildProps<T>) -> Element {
|
||||
render! {
|
||||
div { "{&cx.props.data}" }
|
||||
div { "{&props.data}" }
|
||||
}
|
||||
}
|
||||
+10
-9
@@ -13,23 +13,24 @@ use dioxus::prelude::*;
|
||||
use dioxus_desktop::Config;
|
||||
|
||||
fn main() {
|
||||
let mut vdom = VirtualDom::new(app);
|
||||
let _ = vdom.rebuild();
|
||||
let content = dioxus_ssr::pre_render(&vdom);
|
||||
Config::new()
|
||||
.with_prerendered({
|
||||
// We build the dom a first time, then pre-render it to HTML
|
||||
let pre_rendered_dom = VirtualDom::prebuilt(app);
|
||||
|
||||
dioxus_desktop::launch_cfg(app, Config::new().with_prerendered(content));
|
||||
// We then launch the app with the pre-rendered HTML
|
||||
dioxus_ssr::pre_render(&pre_rendered_dom)
|
||||
})
|
||||
.launch(app);
|
||||
}
|
||||
|
||||
fn app() -> Element {
|
||||
let val = use_signal(|| 0);
|
||||
let mut val = use_signal(|| 0);
|
||||
|
||||
rsx! {
|
||||
div {
|
||||
h1 { "hello world. Count: {val}" }
|
||||
button {
|
||||
onclick: move |_| *val.make_mut() += 1,
|
||||
"click to increment"
|
||||
}
|
||||
button { onclick: move |_| val += 1, "click to increment" }
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
-19
@@ -26,35 +26,31 @@ fn main() {
|
||||
}
|
||||
|
||||
fn app() -> Element {
|
||||
let div_element: Signal<Option<Rc<MountedData>>> = use_signal(|| None);
|
||||
let div_element = use_signal(|| None as Option<Rc<MountedData>>);
|
||||
let dimensions = use_signal(Rect::zero);
|
||||
|
||||
let dimentions = use_signal(Rect::zero);
|
||||
let read_dims = move |_| async move {
|
||||
let read = div_element.read();
|
||||
let client_rect = read.as_ref().map(|el| el.get_client_rect());
|
||||
if let Some(client_rect) = client_rect {
|
||||
if let Ok(rect) = client_rect.await {
|
||||
dimensions.set(rect);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
rsx!(
|
||||
div {
|
||||
width: "50%",
|
||||
height: "50%",
|
||||
background_color: "red",
|
||||
onmounted: move |cx| {
|
||||
div_element.set(Some(cx.inner().clone()));
|
||||
},
|
||||
"This element is {dimentions.read():?}"
|
||||
onmounted: move |cx| div_element.set(Some(cx.inner().clone())),
|
||||
"This element is {dimensions.read():?}"
|
||||
}
|
||||
|
||||
button {
|
||||
onclick: move |_| {
|
||||
to_owned![div_element, dimentions];
|
||||
async move {
|
||||
let read = div_element.read();
|
||||
let client_rect = read.as_ref().map(|el| el.get_client_rect());
|
||||
if let Some(client_rect) = client_rect {
|
||||
if let Ok(rect) = client_rect.await {
|
||||
dimentions.set(rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Read dimentions"
|
||||
onclick: read_dims,
|
||||
"Read dimensions"
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
//! This example just flexes the ability to use arbitrary expressions within RSX.
|
||||
//! It also proves that lifetimes work properly, especially when used with use_ref
|
||||
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
let mut vdom = VirtualDom::new(example);
|
||||
_ = vdom.rebuild();
|
||||
|
||||
let mut renderer = dioxus_ssr::Renderer::new();
|
||||
renderer.pretty = true;
|
||||
renderer.render(&vdom);
|
||||
}
|
||||
|
||||
fn example() -> Element {
|
||||
let items = use_signal(|| {
|
||||
vec![Thing {
|
||||
a: "asd".to_string(),
|
||||
b: 10,
|
||||
}]
|
||||
});
|
||||
|
||||
let things = use_signal(|| {
|
||||
vec![Thing {
|
||||
a: "asd".to_string(),
|
||||
b: 10,
|
||||
}]
|
||||
});
|
||||
let things_list = things.read();
|
||||
|
||||
let mything = use_signal(|| Some(String::from("asd")));
|
||||
let mything_read = mything.read();
|
||||
|
||||
rsx!(
|
||||
div {
|
||||
div { id: "asd",
|
||||
"your neighborhood spiderman"
|
||||
|
||||
for item in items.iter().cycle().take(5) {
|
||||
div { "{item.a}" }
|
||||
}
|
||||
|
||||
for thing in things_list.iter() {
|
||||
div { "{thing.a}" "{thing.b}" }
|
||||
}
|
||||
|
||||
if let Some(f) = mything_read.as_ref() {
|
||||
div { "{f}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
struct Thing {
|
||||
a: String,
|
||||
b: u32,
|
||||
}
|
||||
+5
-10
@@ -241,12 +241,10 @@ fn lowercase_helper() -> Element {
|
||||
|
||||
mod baller {
|
||||
use super::*;
|
||||
#[derive(Props, PartialEq, Eq)]
|
||||
pub struct BallerProps {}
|
||||
|
||||
#[component]
|
||||
/// This component totally balls
|
||||
pub fn Baller(props: BallerProps) -> Element {
|
||||
pub fn Baller() -> Element {
|
||||
todo!()
|
||||
}
|
||||
|
||||
@@ -259,16 +257,13 @@ mod baller {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Props)]
|
||||
pub struct TallerProps<'a> {
|
||||
/// Documention for this component is visible within the rsx macro
|
||||
#[component]
|
||||
pub fn Taller(
|
||||
/// Fields are documented and accessible in rsx!
|
||||
a: &'static str,
|
||||
children: Element,
|
||||
}
|
||||
|
||||
/// Documention for this component is visible within the rsx macro
|
||||
#[component]
|
||||
pub fn Taller(props: TallerProps) -> Element {
|
||||
) -> Element {
|
||||
rsx! {
|
||||
{&cx.props.children}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ fn app() -> Element {
|
||||
}
|
||||
|
||||
button {
|
||||
onclick: async move |_| move {
|
||||
onclick: move |_| async move {
|
||||
if let Some(header) = header_element.read().as_ref().cloned() {
|
||||
let _ = header.scroll_to(ScrollBehavior::Smooth).await;
|
||||
}
|
||||
|
||||
+13
-13
@@ -17,18 +17,13 @@ use dioxus::prelude::*;
|
||||
use dioxus_desktop::{Config, LogicalSize, WindowBuilder};
|
||||
|
||||
fn main() {
|
||||
let cfg = Config::new().with_window(
|
||||
WindowBuilder::new()
|
||||
.with_title("Doggo Fetcher")
|
||||
.with_inner_size(LogicalSize::new(600.0, 800.0)),
|
||||
);
|
||||
|
||||
dioxus_desktop::launch_cfg(app, cfg);
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct DogApi {
|
||||
message: String,
|
||||
Config::new()
|
||||
.with_window(
|
||||
WindowBuilder::new()
|
||||
.with_title("Doggo Fetcher")
|
||||
.with_inner_size(LogicalSize::new(600.0, 800.0)),
|
||||
)
|
||||
.launch(app)
|
||||
}
|
||||
|
||||
fn app() -> Element {
|
||||
@@ -54,6 +49,11 @@ fn app() -> Element {
|
||||
/// actually renders the data.
|
||||
fn Doggo() -> Element {
|
||||
let fut = use_future(|_| async move {
|
||||
#[derive(serde::Deserialize)]
|
||||
struct DogApi {
|
||||
message: String,
|
||||
}
|
||||
|
||||
reqwest::get("https://dog.ceo/api/breeds/image/random/")
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -61,7 +61,7 @@ fn Doggo() -> Element {
|
||||
.await
|
||||
});
|
||||
|
||||
cx.render(match fut.value() {
|
||||
match fut.value() {
|
||||
Some(Ok(resp)) => rsx! {
|
||||
button {
|
||||
onclick: move |_| fut.restart(),
|
||||
|
||||
+73
-71
@@ -1,77 +1,79 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn app() -> Element {
|
||||
rsx!( svg {
|
||||
width: "200",
|
||||
height: "250",
|
||||
xmlns: "http://www.w3.org/2000/svg",
|
||||
version: "1.1",
|
||||
rect {
|
||||
x: "10",
|
||||
y: "10",
|
||||
width: "30",
|
||||
height: "30",
|
||||
stroke: "black",
|
||||
fill: "transparent",
|
||||
stroke_width: "5",
|
||||
}
|
||||
rect {
|
||||
x: "60",
|
||||
y: "10",
|
||||
width: "30",
|
||||
height: "30",
|
||||
stroke: "black",
|
||||
fill: "transparent",
|
||||
stroke_width: "5",
|
||||
}
|
||||
circle {
|
||||
cx: "25",
|
||||
cy: "75",
|
||||
r: "20",
|
||||
stroke: "red",
|
||||
fill: "transparent",
|
||||
stroke_width: "5",
|
||||
}
|
||||
ellipse {
|
||||
cx: "75",
|
||||
cy: "75",
|
||||
rx: "20",
|
||||
ry: "5",
|
||||
stroke: "red",
|
||||
fill: "transparent",
|
||||
stroke_width: "5",
|
||||
}
|
||||
line {
|
||||
x1: "10",
|
||||
x2: "50",
|
||||
y1: "110",
|
||||
y2: "150",
|
||||
stroke: "orange",
|
||||
stroke_width: "5",
|
||||
}
|
||||
polyline {
|
||||
points: "60 110 65 120 70 115 75 130 80 125 85 140 90 135 95 150 100 145",
|
||||
stroke: "orange",
|
||||
fill: "transparent",
|
||||
stroke_width: "5",
|
||||
}
|
||||
polygon {
|
||||
points: "50 160 55 180 70 180 60 190 65 205 50 195 35 205 40 190 30 180 45 180",
|
||||
stroke: "green",
|
||||
fill: "transparent",
|
||||
stroke_width: "5",
|
||||
}
|
||||
path {
|
||||
d: "M20,230 Q40,205 50,230 T90,230",
|
||||
fill: "none",
|
||||
stroke: "blue",
|
||||
stroke_width: "5",
|
||||
}
|
||||
path {
|
||||
d: "M9.00001 9C9 62 103.5 124 103.5 178",
|
||||
stroke: "#3CC4DC",
|
||||
"stroke-linecap": "square",
|
||||
"stroke-width": "square",
|
||||
rsx! {
|
||||
svg {
|
||||
width: "200",
|
||||
height: "250",
|
||||
xmlns: "http://www.w3.org/2000/svg",
|
||||
version: "1.1",
|
||||
rect {
|
||||
x: "10",
|
||||
y: "10",
|
||||
width: "30",
|
||||
height: "30",
|
||||
stroke: "black",
|
||||
fill: "transparent",
|
||||
stroke_width: "5",
|
||||
}
|
||||
rect {
|
||||
x: "60",
|
||||
y: "10",
|
||||
width: "30",
|
||||
height: "30",
|
||||
stroke: "black",
|
||||
fill: "transparent",
|
||||
stroke_width: "5",
|
||||
}
|
||||
circle {
|
||||
cx: "25",
|
||||
cy: "75",
|
||||
r: "20",
|
||||
stroke: "red",
|
||||
fill: "transparent",
|
||||
stroke_width: "5",
|
||||
}
|
||||
ellipse {
|
||||
cx: "75",
|
||||
cy: "75",
|
||||
rx: "20",
|
||||
ry: "5",
|
||||
stroke: "red",
|
||||
fill: "transparent",
|
||||
stroke_width: "5",
|
||||
}
|
||||
line {
|
||||
x1: "10",
|
||||
x2: "50",
|
||||
y1: "110",
|
||||
y2: "150",
|
||||
stroke: "orange",
|
||||
stroke_width: "5",
|
||||
}
|
||||
polyline {
|
||||
points: "60 110 65 120 70 115 75 130 80 125 85 140 90 135 95 150 100 145",
|
||||
stroke: "orange",
|
||||
fill: "transparent",
|
||||
stroke_width: "5",
|
||||
}
|
||||
polygon {
|
||||
points: "50 160 55 180 70 180 60 190 65 205 50 195 35 205 40 190 30 180 45 180",
|
||||
stroke: "green",
|
||||
fill: "transparent",
|
||||
stroke_width: "5",
|
||||
}
|
||||
path {
|
||||
d: "M20,230 Q40,205 50,230 T90,230",
|
||||
fill: "none",
|
||||
stroke: "blue",
|
||||
stroke_width: "5",
|
||||
}
|
||||
path {
|
||||
d: "M9.00001 9C9 62 103.5 124 103.5 178",
|
||||
stroke: "#3CC4DC",
|
||||
"stroke-linecap": "square",
|
||||
"stroke-width": "square",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ pub struct TodoItem {
|
||||
pub contents: String,
|
||||
}
|
||||
|
||||
pub fn app(_props: ()) -> Element {
|
||||
pub fn app() -> Element {
|
||||
let todos = use_signal(|| HashMap::<u32, TodoItem>::new());
|
||||
let filter = use_signal(|| FilterState::All);
|
||||
|
||||
|
||||
+20
-30
@@ -1,34 +1,25 @@
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_desktop::{Config, WindowBuilder};
|
||||
use dioxus_desktop::{window, Config, WindowBuilder};
|
||||
|
||||
fn main() {
|
||||
let cfg = Config::new().with_window(
|
||||
WindowBuilder::new()
|
||||
.with_title("Borderless Window")
|
||||
.with_decorations(false),
|
||||
);
|
||||
|
||||
dioxus_desktop::launch_cfg(app, cfg);
|
||||
Config::new()
|
||||
.with_window(
|
||||
WindowBuilder::new()
|
||||
.with_title("Borderless Window")
|
||||
.with_decorations(false),
|
||||
)
|
||||
.launch(app)
|
||||
}
|
||||
|
||||
fn app() -> Element {
|
||||
let window = dioxus_desktop::use_window(cx);
|
||||
|
||||
// if you want to make window fullscreen, you need close the resizable.
|
||||
// window.set_fullscreen(true);
|
||||
// window.set_resizable(false);
|
||||
|
||||
let fullscreen = use_signal(|| false);
|
||||
let always_on_top = use_signal(|| false);
|
||||
let decorations = use_signal(|| false);
|
||||
|
||||
rsx!(
|
||||
link { href:"https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css", rel:"stylesheet" }
|
||||
header {
|
||||
class: "text-gray-400 bg-gray-900 body-font",
|
||||
onmousedown: move |_| window.drag(),
|
||||
div {
|
||||
class: "container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center",
|
||||
header { class: "text-gray-400 bg-gray-900 body-font", onmousedown: move |_| window().drag(),
|
||||
div { class: "container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center",
|
||||
a { class: "flex title-font font-medium items-center text-white mb-4 md:mb-0",
|
||||
span { class: "ml-3 text-xl", "Dioxus"}
|
||||
}
|
||||
@@ -36,24 +27,23 @@ fn app() -> Element {
|
||||
button {
|
||||
class: "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0",
|
||||
onmousedown: |evt| evt.stop_propagation(),
|
||||
onclick: move |_| window.set_minimized(true),
|
||||
onclick: move |_| window().set_minimized(true),
|
||||
"Minimize"
|
||||
}
|
||||
button {
|
||||
class: "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0",
|
||||
onmousedown: |evt| evt.stop_propagation(),
|
||||
onclick: move |_| {
|
||||
|
||||
window.set_fullscreen(!**fullscreen);
|
||||
window.set_resizable(**fullscreen);
|
||||
fullscreen.modify(|f| !*f);
|
||||
window().set_fullscreen(!*fullscreen());
|
||||
window().set_resizable(*fullscreen());
|
||||
fullscreen.toggle();
|
||||
},
|
||||
"Fullscreen"
|
||||
}
|
||||
button {
|
||||
class: "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0",
|
||||
onmousedown: |evt| evt.stop_propagation(),
|
||||
onclick: move |_| window.close(),
|
||||
onclick: move |_| window().close(),
|
||||
"Close"
|
||||
}
|
||||
}
|
||||
@@ -68,8 +58,8 @@ fn app() -> Element {
|
||||
class: "inline-flex items-center text-white bg-green-500 border-0 py-1 px-3 hover:bg-green-700 rounded",
|
||||
onmousedown: |evt| evt.stop_propagation(),
|
||||
onclick: move |_| {
|
||||
window.set_always_on_top(!always_on_top);
|
||||
always_on_top.set(!always_on_top);
|
||||
window().set_always_on_top(!*always_on_top());
|
||||
always_on_top.toggle();
|
||||
},
|
||||
"Always On Top"
|
||||
}
|
||||
@@ -79,8 +69,8 @@ fn app() -> Element {
|
||||
class: "inline-flex items-center text-white bg-blue-500 border-0 py-1 px-3 hover:bg-green-700 rounded",
|
||||
onmousedown: |evt| evt.stop_propagation(),
|
||||
onclick: move |_| {
|
||||
window.set_decorations(!decorations);
|
||||
decorations.set(!decorations);
|
||||
window().set_decorations(!*decorations());
|
||||
decorations.toggle();
|
||||
},
|
||||
"Set Decorations"
|
||||
}
|
||||
@@ -89,7 +79,7 @@ fn app() -> Element {
|
||||
button {
|
||||
class: "inline-flex items-center text-white bg-blue-500 border-0 py-1 px-3 hover:bg-green-700 rounded",
|
||||
onmousedown: |evt| evt.stop_propagation(),
|
||||
onclick: move |_| window.set_title("Dioxus Application"),
|
||||
onclick: move |_| window().set_title("Dioxus Application"),
|
||||
"Change Title"
|
||||
}
|
||||
}
|
||||
|
||||
+12
-16
@@ -5,37 +5,33 @@ use dioxus_desktop::use_wry_event_handler;
|
||||
use dioxus_desktop::{Config, WindowCloseBehaviour};
|
||||
|
||||
fn main() {
|
||||
let cfg = Config::new().with_close_behaviour(WindowCloseBehaviour::CloseWindow);
|
||||
|
||||
dioxus_desktop::launch_cfg(app, cfg);
|
||||
Config::new()
|
||||
.with_close_behaviour(WindowCloseBehaviour::CloseWindow)
|
||||
.launch(app)
|
||||
}
|
||||
|
||||
fn app() -> Element {
|
||||
let focused = use_signal(|| false);
|
||||
|
||||
use_wry_event_handler(move |event, _| {
|
||||
if let WryEvent::WindowEvent {
|
||||
use_wry_event_handler(move |event, _| match event {
|
||||
WryEvent::WindowEvent {
|
||||
event: WindowEvent::Focused(new_focused),
|
||||
..
|
||||
} = event
|
||||
{
|
||||
focused.set(*new_focused);
|
||||
}
|
||||
} => focused.set(*new_focused),
|
||||
_ => {}
|
||||
});
|
||||
|
||||
rsx! {
|
||||
div{
|
||||
div {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
flex_direction: "column",
|
||||
align_items: "center",
|
||||
{
|
||||
if *focused.get() {
|
||||
"This window is focused!"
|
||||
} else {
|
||||
"This window is not focused!"
|
||||
}
|
||||
if *focused() {
|
||||
"This window is focused!"
|
||||
} else {
|
||||
"This window is not focused!"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ fn app() -> Element {
|
||||
input {
|
||||
r#type: "number",
|
||||
value: "{level}",
|
||||
oninput: |e| {
|
||||
oninput: move |e| {
|
||||
if let Ok(new_zoom) = e.value().parse::<f64>() {
|
||||
level.set(new_zoom);
|
||||
dioxus_desktop::window().webview.zoom(new_zoom);
|
||||
|
||||
@@ -230,6 +230,13 @@ impl VirtualDom {
|
||||
Self::new_with_props(|app| app(), app)
|
||||
}
|
||||
|
||||
/// Create a new virtualdom and build it immediately
|
||||
pub fn prebuilt(app: fn() -> Element) -> Self {
|
||||
let mut dom = Self::new(app);
|
||||
dom.rebuild_in_place();
|
||||
dom
|
||||
}
|
||||
|
||||
/// Create a new VirtualDom with the given properties for the root component.
|
||||
///
|
||||
/// # Description
|
||||
@@ -568,6 +575,14 @@ impl VirtualDom {
|
||||
to.append_children(ElementId(0), m);
|
||||
}
|
||||
|
||||
/// Rebuild the virtualdom without handling any of the mutations
|
||||
///
|
||||
/// This is useful for testing purposes and in cases where you render the output of the virtualdom without
|
||||
/// handling any of its mutations.
|
||||
pub fn rebuild_in_place(&mut self) {
|
||||
self.rebuild(&mut NoOpMutations);
|
||||
}
|
||||
|
||||
/// [`VirtualDom::rebuild`] to a vector of mutations for testing purposes
|
||||
pub fn rebuild_to_vec(&mut self) -> Mutations {
|
||||
let mut mutations = Mutations::default();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::borrow::Cow;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use dioxus_core::prelude::Component;
|
||||
use dioxus_core::prelude::{Component, Element};
|
||||
use tao::window::{Icon, WindowBuilder, WindowId};
|
||||
use wry::{
|
||||
http::{Request as HttpRequest, Response as HttpResponse},
|
||||
@@ -74,8 +74,8 @@ impl Config {
|
||||
/// Launch a Dioxus app using the given component and config
|
||||
///
|
||||
/// See the [`crate::launch::launch`] function for more details.
|
||||
pub fn launch(self, root: Component<()>) {
|
||||
crate::launch::launch_cfg(root, self)
|
||||
pub fn launch(self, app: fn() -> Element) {
|
||||
self.launch_with_props(|props| props(), app)
|
||||
}
|
||||
|
||||
/// Launch a Dioxus app using the given component, config, and props
|
||||
|
||||
@@ -2,6 +2,7 @@ use crate::{
|
||||
assets::*, ipc::UserWindowEvent, shortcut::IntoAccelerator, window, DesktopContext,
|
||||
ShortcutHandle, ShortcutRegistryError, WryEventHandler,
|
||||
};
|
||||
use dioxus_core::use_hook;
|
||||
use tao::{event::Event, event_loop::EventLoopWindowTarget};
|
||||
use wry::RequestAsyncResponder;
|
||||
|
||||
@@ -12,22 +13,21 @@ use wry::RequestAsyncResponder;
|
||||
// .unwrap()
|
||||
// }
|
||||
|
||||
// /// Get a closure that executes any JavaScript in the WebView context.
|
||||
// pub fn use_wry_event_handler(
|
||||
// ,
|
||||
// handler: impl FnMut(&Event<UserWindowEvent>, &EventLoopWindowTarget<UserWindowEvent>) + 'static,
|
||||
// ) -> &WryEventHandler {
|
||||
// cx.use_hook(move || {
|
||||
// let desktop = window();
|
||||
/// Get a closure that executes any JavaScript in the WebView context.
|
||||
pub fn use_wry_event_handler(
|
||||
handler: impl FnMut(&Event<UserWindowEvent>, &EventLoopWindowTarget<UserWindowEvent>) + 'static,
|
||||
) -> WryEventHandler {
|
||||
use_hook(move || {
|
||||
let desktop = window();
|
||||
|
||||
// let id = desktop.create_wry_event_handler(handler);
|
||||
let id = desktop.create_wry_event_handler(handler);
|
||||
|
||||
// WryEventHandler {
|
||||
// handlers: desktop.shared.event_handlers.clone(),
|
||||
// id,
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
WryEventHandler {
|
||||
handlers: desktop.shared.event_handlers.clone(),
|
||||
id,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// /// Provide a callback to handle asset loading yourself.
|
||||
// ///
|
||||
|
||||
@@ -23,8 +23,8 @@ use tao::event::{Event, StartCause, WindowEvent};
|
||||
/// })
|
||||
/// }
|
||||
/// ```
|
||||
pub fn launch(root: fn() -> Element) {
|
||||
launch_with_props(|root| root(), root, Config::default())
|
||||
pub fn launch(app: fn() -> Element) {
|
||||
launch_with_props(|root| root(), app, Config::default())
|
||||
}
|
||||
|
||||
/// Launch the WebView and run the event loop, with configuration.
|
||||
@@ -47,8 +47,8 @@ pub fn launch(root: fn() -> Element) {
|
||||
/// })
|
||||
/// }
|
||||
/// ```
|
||||
pub fn launch_cfg(root: Component, config_builder: Config) {
|
||||
launch_with_props(root, (), config_builder)
|
||||
pub fn launch_cfg(app: fn() -> Element, config_builder: Config) {
|
||||
launch_with_props(|props| props(), app, config_builder)
|
||||
}
|
||||
|
||||
/// Launch the WebView and run the event loop, with configuration and root props.
|
||||
|
||||
@@ -46,3 +46,5 @@ pub use desktop_context::{
|
||||
// pub use hooks::{use_asset_handler, use_global_shortcut, use_window, use_wry_event_handler};
|
||||
pub use shortcut::{ShortcutHandle, ShortcutId, ShortcutRegistryError};
|
||||
pub use wry::RequestAsyncResponder;
|
||||
|
||||
pub use hooks::*;
|
||||
@@ -7,8 +7,11 @@ use std::{
|
||||
};
|
||||
|
||||
use dioxus_core::{
|
||||
prelude::{current_scope_id, has_context, provide_context, schedule_update_any},
|
||||
use_hook, ScopeId,
|
||||
prelude::{
|
||||
current_scope_id, has_context, provide_context, schedule_update_any, use_hook,
|
||||
IntoAttributeValue,
|
||||
},
|
||||
ScopeId,
|
||||
};
|
||||
use generational_box::{GenerationalRef, GenerationalRefMut};
|
||||
|
||||
@@ -306,6 +309,15 @@ impl<T: 'static> Signal<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoAttributeValue for Signal<T>
|
||||
where
|
||||
T: Clone + IntoAttributeValue,
|
||||
{
|
||||
fn into_value(self) -> dioxus_core::AttributeValue {
|
||||
self.with(|f| f.clone().into_value())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + 'static> Signal<T> {
|
||||
/// Get the current value of the signal. This will subscribe the current scope to the signal.
|
||||
/// If the signal has been dropped, this will panic.
|
||||
|
||||
Reference in new issue
Block a user