Bring back mroe hooks, remove old hooks, cleanup a number of examples

This commit is contained in:
Jonathan Kelley committed 2024-01-15 17:04:39 -08:00
1 parent b291a5c0b0
commit 74aa55f85f
33 files changed
+179 -643

No files matched your search

+3 -3
View File
@@ -22,7 +22,7 @@ fn app() -> Element {
dioxus_desktop::window().new_window(
VirtualDom::new_with_props(compose, tx.clone()),
Default::default(),
)
);
};
rsx! {
@@ -39,7 +39,7 @@ fn app() -> Element {
}
}
fn compose(receiver: UnboundedSender<String>) -> Element {
fn compose(tx: UnboundedSender<String>) -> Element {
let user_input = use_signal(String::new);
rsx! {
@@ -48,7 +48,7 @@ fn compose(receiver: UnboundedSender<String>) -> Element {
button {
onclick: move |_| {
cx.props.app_tx.send(user_input.get().clone());
tx.send(user_input.get().clone());
dioxus_desktop::window().close();
},
"Click to send"
+1 -1
View File
@@ -9,7 +9,7 @@ fn main() {
fn app() -> Element {
let counters = use_signal(|| vec![0, 0, 0]);
let sum = use_selector(move || counters.read().iter().copied().sum() as usize);
let sum = use_selector(move || counters.read().iter().copied().sum::<usize>());
render! {
div {
-7
View File
@@ -24,12 +24,8 @@ pub struct Client {
pub description: String,
}
type ClientContext = Vec<Client>;
#[component]
fn App() -> Element {
use_shared_state_provider::<ClientContext>(Default::default);
render! {
link {
rel: "stylesheet",
@@ -54,8 +50,6 @@ fn App() -> Element {
#[component]
fn ClientList() -> Element {
let clients = use_shared_state::<ClientContext>().unwrap();
rsx! {
h2 { "List of Clients" }
Link { to: Route::ClientAdd {}, class: "pure-button pure-button-primary", "Add Client" }
@@ -71,7 +65,6 @@ fn ClientList() -> Element {
#[component]
fn ClientAdd() -> Element {
let clients = use_shared_state::<ClientContext>().unwrap();
let first_name = use_signal(String::new);
let last_name = use_signal(String::new);
let description = use_signal(String::new);
+21 -31
View File
@@ -5,15 +5,10 @@ fn main() {
dioxus_desktop::launch(app);
}
#[derive(Debug, Clone, PartialEq, serde::Deserialize)]
struct ListBreeds {
message: HashMap<String, Vec<String>>,
}
fn app() -> Element {
let breed = use_signal(|| "deerhound".to_string());
let breeds = use_future(|| async move {
let breed_list = use_future(|| async move {
reqwest::get("https://dog.ceo/api/breeds/list/all")
.await
.unwrap()
@@ -21,13 +16,13 @@ fn app() -> Element {
.await
});
match breeds.value()? {
Ok(breed_list) => rsx! {
match breed_list.value().read().as_ref() {
Some(Ok(breeds)) => rsx! {
div { height: "500px",
h1 { "Select a dog breed!" }
div { display: "flex",
ul { flex: "50%",
for cur_breed in breed_list.message.keys().take(10) {
for cur_breed in breeds.message.keys().take(10).cloned() {
li { key: "{cur_breed}",
button { onclick: move |_| breed.set(cur_breed.clone()), "{cur_breed}" }
}
@@ -37,18 +32,13 @@ fn app() -> Element {
}
}
},
Err(_e) => rsx! { div { "Error fetching breeds" } },
_ => rsx! { div { "loading breeds" } },
}
}
#[derive(serde::Deserialize, Debug)]
struct DogApi {
message: String,
}
#[component]
fn BreedPic(breed: Signal<String>) -> Element {
let fut = use_future(|breed| async move {
let fut = use_future(|| async move {
reqwest::get(format!("https://dog.ceo/api/breed/{breed}/images/random"))
.await
.unwrap()
@@ -56,23 +46,23 @@ fn BreedPic(breed: Signal<String>) -> Element {
.await
});
match fut.value()? {
Ok(resp) => render! {
match fut.value().read().as_ref() {
Some(Ok(resp)) => rsx! {
div {
button {
onclick: move |_| {
println!("clicked");
fut.restart()
},
"Click to fetch another doggo"
}
img {
src: "{resp.message}",
max_width: "500px",
max_height: "500px",
}
button { onclick: move |_| fut.restart(), "Click to fetch another doggo" }
img { max_width: "500px", max_height: "500px", src: "{resp.message}" }
}
},
Err(_) => render! { div { "loading dogs failed" } },
_ => rsx! { div { "loading dog picture" } },
}
}
#[derive(Debug, Clone, PartialEq, serde::Deserialize)]
struct ListBreeds {
message: HashMap<String, Vec<String>>,
}
#[derive(serde::Deserialize, Debug)]
struct DogApi {
message: String,
}
+1 -1
View File
@@ -1,7 +1,7 @@
use dioxus::{core::CapturedError, prelude::*};
fn main() {
dioxus_desktop::launch(App);
dioxus_desktop::launch(app);
}
fn app() -> Element {
+5 -9
View File
@@ -5,8 +5,8 @@ fn main() {
}
fn app() -> Element {
let future = use_future(|_| async move {
let eval = eval(
let future = use_future(|| async move {
let mut eval = eval(
r#"
dioxus.send("Hi from JS!");
let msg = await dioxus.recv();
@@ -22,12 +22,8 @@ fn app() -> Element {
res
});
match future.value() {
Some(v) => rsx!(
p { "{v}" }
),
_ => rsx!(
p { "hello" }
),
match future.value().read().as_ref() {
Some(v) => rsx!( p { "{v}" } ),
_ => rsx!( p { "waiting.." } ),
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ fn main() {
.launch(app)
}
fn app(_props: ()) -> Element {
fn app() -> Element {
rsx!(
div {
h1 { "drag a file here and check your console" }
-152
View File
@@ -1,152 +0,0 @@
#![allow(non_snake_case)]
use dioxus::prelude::*;
use rand::prelude::*;
fn main() {
dioxus_desktop::launch(app);
}
#[derive(Clone, PartialEq)]
struct Label {
key: usize,
labels: [&'static str; 3],
}
impl Label {
fn new_list(num: usize) -> Vec<Self> {
let mut rng = SmallRng::from_entropy();
let mut labels = Vec::with_capacity(num);
for x in 0..num {
labels.push(Label {
key: x,
labels: [
ADJECTIVES.choose(&mut rng).unwrap(),
COLOURS.choose(&mut rng).unwrap(),
NOUNS.choose(&mut rng).unwrap(),
],
});
}
labels
}
}
fn app() -> Element {
let items = use_signal(Vec::new);
let selected = use_signal(|| None);
rsx! {
div { class: "container",
div { class: "jumbotron",
div { class: "row",
div { class: "col-md-6", h1 { "Dioxus" } }
div { class: "col-md-6",
div { class: "row",
ActionButton { name: "Create 1,000 rows", id: "run",
onclick: move |_| items.set(Label::new_list(1_000)),
}
ActionButton { name: "Create 10,000 rows", id: "runlots",
onclick: move |_| items.set(Label::new_list(10_000)),
}
ActionButton { name: "Append 1,000 rows", id: "add",
onclick: move |_| items.write().extend(Label::new_list(1_000)),
}
ActionButton { name: "Update every 10th row", id: "update",
onclick: move |_| items.write().iter_mut().step_by(10).for_each(|item| item.labels[2] = "!!!"),
}
ActionButton { name: "Clear", id: "clear",
onclick: move |_| items.write().clear(),
}
ActionButton { name: "Swap rows", id: "swaprows",
onclick: move |_| items.write().swap(0, 998),
}
}
}
}
}
table {
tbody {
for (id, item) in items.read().iter().enumerate() {
tr {
class: if (*selected).map(|s| s == id).unwrap_or(false) { "danger" },
td { class:"col-md-1" }
td { class:"col-md-1", "{item.key}" }
td { class:"col-md-1", onclick: move |_| selected.set(Some(id)),
a { class: "lbl", "{item.labels[0]}{item.labels[1]}{item.labels[2]}" }
}
td { class: "col-md-1",
a { class: "remove", onclick: move |_| { items.write().remove(id); },
span { class: "glyphicon glyphicon-remove remove", aria_hidden: "true" }
}
}
td { class: "col-md-6" }
}
}
}
}
span { class: "preloadicon glyphicon glyphicon-remove", aria_hidden: "true" }
}
}
}
#[derive(Props)]
struct ActionButtonProps<'a> {
name: &'a str,
id: &'a str,
onclick: EventHandler<'a>,
}
fn ActionButton(props: ActionButtonProps) -> Element {
rsx! {
div {
class: "col-sm-6 smallpad",
button {
class:"btn btn-primary btn-block",
r#type: "button",
id: "{cx.props.id}",
onclick: move |_| cx.props.onclick.call(()),
"{cx.props.name}"
}
}
}
}
static ADJECTIVES: &[&str] = &[
"pretty",
"large",
"big",
"small",
"tall",
"short",
"long",
"handsome",
"plain",
"quaint",
"clean",
"elegant",
"easy",
"angry",
"crazy",
"helpful",
"mushy",
"odd",
"unsightly",
"adorable",
"important",
"inexpensive",
"cheap",
"expensive",
"fancy",
];
static COLOURS: &[&str] = &[
"red", "yellow", "blue", "green", "pink", "brown", "purple", "brown", "white", "black",
"orange",
];
static NOUNS: &[&str] = &[
"table", "chair", "house", "bbq", "desk", "car", "pony", "cookie", "sandwich", "burger",
"pizza", "mouse", "keyboard",
];
@@ -129,7 +129,7 @@ pub fn RefreshToken(cx: Scope<ClientProps>) -> Element {
#[component]
pub fn LoadClient() -> Element {
let init_client_future = use_future(|_| async move { init_oidc_client().await });
let init_client_future = use_future(|| async move { init_oidc_client().await });
let fermi_client: &UseAtomRef<ClientState> = use_atom_ref(&FERMI_CLIENT);
cx.render(match init_client_future.value() {
Some(client_props) => match client_props {
+7 -7
View File
@@ -35,7 +35,7 @@ fn app() -> Element {
type SthElse<T> = Option<T>;
#[derive(Props, PartialEq)]
#[derive(Props, PartialEq, Clone)]
struct ButtonProps {
a: String,
@@ -51,14 +51,14 @@ struct ButtonProps {
e: SthElse<String>,
}
fn Button(cx: Scope<ButtonProps>) -> Element {
fn Button(props: ButtonProps) -> Element {
rsx! {
button {
"{cx.props.a} | "
"{cx.props.b:?} | "
"{cx.props.c:?} | "
"{cx.props.d:?} | "
"{cx.props.e:?}"
"{props.a} | "
"{props.b:?} | "
"{props.c:?} | "
"{props.d:?} | "
"{props.e:?}"
}
}
}
+7 -10
View File
@@ -120,20 +120,17 @@ fn app() -> Element {
}
}
#[derive(Props)]
struct CalculatorKeyProps {
#[props(into)]
name: String,
#[component]
fn CalculatorKey(
#[props(into)] name: String,
onclick: EventHandler<MouseEvent>,
children: Element,
}
fn CalculatorKey(props: CalculatorKeyProps) -> Element {
) -> Element {
rsx! {
button {
class: "calculator-key {cx.props.name}",
onclick: move |e| cx.props.onclick.call(e),
{&cx.props.children}
class: "calculator-key {name}",
onclick: move |e| onclick.call(e),
{&children}
}
}
}
+3 -7
View File
@@ -20,13 +20,9 @@ fn app() -> Element {
rsx!(
div {
h1 {"Select an option"}
h3 { "The radio is... ", {state.is_playing()}, "!" }
button { onclick: move |_| state.make_mut().reduce(PlayerAction::Pause),
"Pause"
}
button { onclick: move |_| state.make_mut().reduce(PlayerAction::Play),
"Play"
}
h3 { "The radio is... ", {state.read().is_playing()}, "!" }
button { onclick: move |_| state.write().reduce(PlayerAction::Pause), "Pause" }
button { onclick: move |_| state.write().reduce(PlayerAction::Play), "Play" }
}
)
}
+1 -1
View File
@@ -45,7 +45,7 @@ fn app() -> Element {
height: "50%",
background_color: "red",
onmounted: move |cx| div_element.set(Some(cx.inner().clone())),
"This element is {dimensions.read():?}"
"This element is {*dimensions():?}"
}
button {
-73
View File
@@ -1,73 +0,0 @@
use std::collections::HashMap;
use dioxus::prelude::*;
fn main() {
dioxus_desktop::launch(App);
}
#[derive(Default)]
struct CoolData {
data: HashMap<usize, String>,
}
impl CoolData {
pub fn new(data: HashMap<usize, String>) -> Self {
Self { data }
}
pub fn view(&self, id: &usize) -> Option<&String> {
self.data.get(id)
}
pub fn set(&mut self, id: usize, data: String) {
self.data.insert(id, data);
}
}
#[component]
#[rustfmt::skip]
pub fn App() -> Element {
use_shared_state_provider(|| CoolData::new(HashMap::from([
(0, "Hello, World!".to_string()),
(1, "Dioxus is amazing!".to_string())
])));
render!(
DataEditor {
id: 0
}
DataEditor {
id: 1
}
DataView {
id: 0
}
DataView {
id: 1
}
)
}
#[component]
fn DataEditor(id: usize) -> Element {
let data = use_shared_state::<CoolData>()?;
render! {
p {
{data.read().view(id)?}
}
}
}
#[component]
fn DataView(id: usize) -> Element {
let data = use_shared_state::<CoolData>()?;
render! {
input {
oninput: move |e: FormEvent| data.write().set(*id, e.value()),
value: data.read().view(id)?
}
}
}
+1 -1
View File
@@ -8,7 +8,7 @@ fn main() {
fn app() -> Element {
let toggled = use_signal(|| false);
use_global_shortcut("ctrl+s", move || toggled.toggle());
_ = use_global_shortcut("ctrl+s", move || toggled.toggle());
rsx!("toggle: {toggled}")
}
+2 -2
View File
@@ -54,13 +54,13 @@ fn NavBar() -> Element {
#[component]
fn Home() -> Element {
log::debug!("rendering home {:?}", cx.scope_id());
log::debug!("rendering home {:?}", current_scope_id());
render! { h1 { "Home" } }
}
#[component]
fn BlogList() -> Element {
log::debug!("rendering blog list {:?}", cx.scope_id());
log::debug!("rendering blog list {:?}", current_scope_id());
render! { div { "Blog List" } }
}
+1 -1
View File
@@ -38,5 +38,5 @@ fn Nav() -> Element {
}
fn main() {
dioxus_desktop::launch(|cx| render!(Router::<Route> {}));
dioxus_desktop::launch(|| render!(Router::<Route> {}));
}
+1
View File
@@ -31,6 +31,7 @@ fn Component(props: Props) -> Element {
struct Props {
#[props(extends = GlobalAttributes)]
attributes: Vec<Attribute>,
extra_data: String,
extra_data2: String,
}
+1 -1
View File
@@ -13,7 +13,7 @@ fn main() {
// Or we can render rsx! calls themselves
println!(
"{}",
dioxus_ssr::render_lazy(rsx! {
dioxus_ssr::render_element(rsx! {
div {
h1 { "Hello, world!" }
}
+1 -1
View File
@@ -10,7 +10,7 @@ fn main() {
fn app() -> Element {
let count = use_signal(|| 10);
use_future(|_| async move {
use_future(|| async move {
let mut stream = some_stream();
while let Some(second) = stream.next().await {
+2 -2
View File
@@ -48,7 +48,7 @@ fn app() -> Element {
/// Suspense is achieved my moving the future into only the component that
/// actually renders the data.
fn Doggo() -> Element {
let fut = use_future(|_| async move {
let fut = use_future(|| async move {
#[derive(serde::Deserialize)]
struct DogApi {
message: String,
@@ -61,7 +61,7 @@ fn Doggo() -> Element {
.await
});
match fut.value() {
match fut.value().read().as_ref() {
Some(Ok(resp)) => rsx! {
button {
onclick: move |_| fut.restart(),