feat: mvoe away from compound context

This commit is contained in:
Jonathan Kelley committed 2021-09-21 13:42:52 -04:00
1 parent bfdcb20437
commit a2c7d17b05
103 files changed
+309 -293

No files matched your search

+1 -1
View File
@@ -15,7 +15,7 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let (state, set_state) = use_state_classic(cx, || 0);
cx.render(rsx! {
div {
+1 -1
View File
@@ -27,7 +27,7 @@ enum Operator {
Div,
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let (cur_val, set_cur_val) = use_state_classic(cx, || 0.0_f64);
let (operator, set_operator) = use_state_classic(cx, || None as Option<Operator>);
let (display_value, set_display_value) = use_state_classic(cx, || "0".to_string());
+2 -2
View File
@@ -13,7 +13,7 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
cx.render(rsx! {
Calcier {
h2 {"abc 1"}
@@ -25,7 +25,7 @@ static App: FC<()> = |cx| {
})
};
static Calcier: FC<()> = |cx| {
static Calcier: FC<()> = |cx, props| {
cx.render(rsx! {
div {
h1 {
+1 -1
View File
@@ -25,7 +25,7 @@ fn main() {
#[derive(Debug)]
struct CustomContext([&'static str; 3]);
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props|{
cx.use_create_context(|| CustomContext(["Jack", "Jill", "Bob"]));
cx.render(rsx! {
+1 -1
View File
@@ -13,7 +13,7 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
cx.render(rsx! {
h2 { "abc 1" }
div {
+1 -1
View File
@@ -13,7 +13,7 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example));
}
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
let nodes = (0..500).map(|f| rsx! (li {"div"}));
cx.render(rsx! {
div {
+2 -2
View File
@@ -14,7 +14,7 @@ fn main() {
}
// this is a component
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props|{
let (event, set_event) = use_state_classic(cx, || None);
let handler = move |evt| {
@@ -50,7 +50,7 @@ struct ExampleProps {
name: String,
}
pub static Example2: FC<ExampleProps> = |cx| {
pub static Example2: FC<ExampleProps> = |cx, props|{
cx.render(rsx! {
div {
h1 {"hello {cx.name}"}
+3 -3
View File
@@ -12,7 +12,7 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props|{
let (val, set_val) = use_state_classic(cx, || "asd".to_string());
cx.render(rsx! {
@@ -37,7 +37,7 @@ static App: FC<()> = |cx| {
})
};
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props|{
cx.render(rsx! {
div { class: "max-w-lg max-w-xs bg-blue-800 shadow-2xl rounded-lg mx-auto text-center py-12 mt-4 rounded-xl"
div { class: "container py-5 max-w-md mx-auto"
@@ -50,7 +50,7 @@ pub static Example: FC<()> = |cx| {
})
};
static UserInput: FC<()> = |cx| {
static UserInput: FC<()> = |cx, props|{
let (val, set_val) = use_state_classic(cx, || "asd".to_string());
rsx! { in cx,
+1 -1
View File
@@ -9,7 +9,7 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example))
}
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
let (name, set_name) = use_state_classic(cx, || "...?");
log::debug!("Running component....");
+1 -1
View File
@@ -9,7 +9,7 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example))
}
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
let (name, set_name) = use_state_classic(cx, || "...?");
cx.render(rsx! {
section { class: "py-12 px-4 text-center"
+1 -1
View File
@@ -14,7 +14,7 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let (contents, set_contents) = use_state_classic(cx, || "asd");
cx.render(rsx! {
+1 -1
View File
@@ -13,7 +13,7 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let (contents, set_contents) = use_state_classic(cx, || "asd");
cx.render(rsx! {
+1 -1
View File
@@ -26,7 +26,7 @@ pub struct TodoItem {
pub contents: String,
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let (draft, set_draft) = use_state_classic(cx, || "".to_string());
let (filter, set_filter) = use_state_classic(cx, || FilterState::All);
let todos = use_state(cx, || BTreeMap::<uuid::Uuid, TodoItem>::new());
+1 -1
View File
@@ -11,7 +11,7 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example));
}
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
cx.render(rsx! {
div {
span {
+1 -1
View File
@@ -31,7 +31,7 @@ fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let state = use_model(&cx, || Calculator::new());
let clear_display = state.display_value.eq("0");
+1 -1
View File
@@ -27,7 +27,7 @@ struct ExampleProps {
initial_name: &'static str,
}
pub static Example: FC<ExampleProps> = |cx| {
pub static Example: FC<ExampleProps> = |cx, props|{
let name = use_state(cx, move || cx.initial_name);
cx.render(rsx! {
+1 -1
View File
@@ -11,7 +11,7 @@ use dioxus_web::{prelude::*, WebsysRenderer};
static APP_STYLE: &'static str = include_str!("./style.css");
fn main() {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(|cx| {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(|cx, props| {
cx.render(rsx! {
div {
id: "app"
+1 -1
View File
@@ -9,7 +9,7 @@ fn main() {
wasm_logger::init(wasm_logger::Config::new(log::Level::Debug));
console_error_panic_hook::set_once();
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(|cx| {
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(|cx, props| {
cx.render(html! {
<div>
<div class="flex items-center justify-center flex-col">
+1 -1
View File
@@ -7,7 +7,7 @@ fn main() {
dioxus::desktop::launch(App, |c| c).expect("faield to launch");
}
pub static App: FC<()> = |cx| {
pub static App: FC<()> = |cx, props| {
let count = use_state(cx, || 0);
let mut direction = use_state(cx, || 1);
+7 -7
View File
@@ -22,7 +22,7 @@ fn main() {
dioxus::desktop::launch(App, |c| c);
}
fn App<'a>(cx: Context<'a, ()>) -> DomTree<'a> {
fn App<'a>(cx: Context<'a>, props: &()) -> DomTree<'a> {
let text: &'a mut Vec<String> = cx.use_hook(|_| vec![String::from("abc=def")], |f| f, |_| {});
let first = text.get_mut(0).unwrap();
@@ -45,8 +45,8 @@ impl<'a> Drop for C1Props<'a> {
fn drop(&mut self) {}
}
fn Child1<'a>(cx: Context<'a, C1Props>) -> DomTree<'a> {
let (left, right) = cx.text.split_once("=").unwrap();
fn Child1<'a>(cx: Context<'a>, props: &'a C1Props) -> DomTree<'a> {
let (left, right) = props.text.split_once("=").unwrap();
cx.render(rsx! {
div {
@@ -66,10 +66,10 @@ impl<'a> Drop for C2Props<'a> {
}
}
fn Child2<'a>(cx: Context<'a, C2Props>) -> DomTree<'a> {
fn Child2<'a>(cx: Context<'a>, props: &'a C2Props) -> DomTree<'a> {
cx.render(rsx! {
Child3 {
text: cx.text
text: props.text
}
})
}
@@ -79,8 +79,8 @@ struct C3Props<'a> {
text: &'a str,
}
fn Child3<'a>(cx: Context<'a, C3Props>) -> DomTree<'a> {
fn Child3<'a>(cx: Context<'a>, props: &C3Props) -> DomTree<'a> {
cx.render(rsx! {
div { "{cx.text}"}
div { "{props.text}"}
})
}
+16 -16
View File
@@ -19,7 +19,7 @@ enum Operator {
Div,
}
const App: FC<()> = |cx| {
const App: FC<()> = |cx, props| {
let cur_val = use_state(cx, || 0.0_f64);
let operator = use_state(cx, || None as Option<Operator>);
let display_value = use_state(cx, || "".to_string());
@@ -70,16 +70,16 @@ const App: FC<()> = |cx| {
display_value.modify().pop();
}
}
KeyCode::_0 => input_digit(0),
KeyCode::_1 => input_digit(1),
KeyCode::_2 => input_digit(2),
KeyCode::_3 => input_digit(3),
KeyCode::_4 => input_digit(4),
KeyCode::_5 => input_digit(5),
KeyCode::_6 => input_digit(6),
KeyCode::_7 => input_digit(7),
KeyCode::_8 => input_digit(8),
KeyCode::_9 => input_digit(9),
KeyCode::Num0 => input_digit(0),
KeyCode::Num1 => input_digit(1),
KeyCode::Num2 => input_digit(2),
KeyCode::Num3 => input_digit(3),
KeyCode::Num4 => input_digit(4),
KeyCode::Num5 => input_digit(5),
KeyCode::Num6 => input_digit(6),
KeyCode::Num7 => input_digit(7),
KeyCode::Num8 => input_digit(8),
KeyCode::Num9 => input_digit(9),
KeyCode::Add => operator.set(Some(Operator::Add)),
KeyCode::Subtract => operator.set(Some(Operator::Sub)),
KeyCode::Divide => operator.set(Some(Operator::Div)),
@@ -124,11 +124,11 @@ struct CalculatorKeyProps<'a> {
onclick: &'a dyn Fn(MouseEvent),
}
fn CalculatorKey<'a, 'r>(cx: Context<'a, CalculatorKeyProps<'r>>) -> DomTree<'a> {
fn CalculatorKey<'a>(cx: Context<'a>, props: &'a CalculatorKeyProps) -> DomTree<'a> {
cx.render(rsx! {
button {
class: "calculator-key {cx.name}"
onclick: {cx.onclick}
class: "calculator-key {props.name}"
onclick: {props.onclick}
{cx.children()}
}
})
@@ -139,10 +139,10 @@ struct CalculatorDisplayProps {
val: f64,
}
fn CalculatorDisplay(cx: Context<CalculatorDisplayProps>) -> DomTree {
fn CalculatorDisplay<'a>(cx: Context<'a>, props: &CalculatorDisplayProps) -> DomTree<'a> {
use separator::Separatable;
// Todo, add float support to the num-format crate
let formatted = cx.val.separated_string();
let formatted = props.val.separated_string();
// TODO: make it autoscaling with css
cx.render(rsx! {
div { class: "calculator-display"
+2 -2
View File
@@ -27,7 +27,7 @@ fn main() {
use dioxus::prelude::*;
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let p1 = use_state(cx, || 0);
let p2 = use_state(cx, || 0);
@@ -59,7 +59,7 @@ struct HorseyProps {
pos: i32,
}
static Horsey: FC<HorseyProps> = |cx| {
static Horsey: FC<HorseyProps> = |cx, props| {
cx.render(rsx! {
div {
button { "pause" }
+1 -1
View File
@@ -19,7 +19,7 @@ fn main() {
.expect("Webview finished");
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let state = use_model(&cx, || Calculator::new());
let clear_display = state.display_value.eq("0");
+2 -2
View File
@@ -17,7 +17,7 @@ fn main() {
.expect("Webview finished");
}
// pub static Example: FC<()> = |cx| {
// pub static Example: FC<()> = |cx, props|{
// cx.render(html! {
// <div>
// <svg class="octicon octicon-star v-align-text-bottom"
@@ -36,7 +36,7 @@ fn main() {
// </div>
// })
// };
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
cx.render(rsx! {
div {
class: "flex items-center justify-center flex-col"
+1 -1
View File
@@ -17,7 +17,7 @@ fn main() {
.expect("Webview finished");
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let hifives = use_model(&cx, || 0);
cx.render(rsx! {
div {
+1 -1
View File
@@ -20,7 +20,7 @@ fn main() {
.unwrap();
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let files = use_state(cx, || Files::new());
let file_list = files.path_names.iter().enumerate().map(|(dir_id, path)| {
+7 -7
View File
@@ -19,7 +19,7 @@ fn main() {
// We use a special immutable hashmap to make hashmap operations efficient
type RowList = im_rc::HashMap<usize, Rc<str>, FxBuildHasher>;
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let items = use_state(cx, || RowList::default());
let create_rendered_rows = move |from, num| move |_| items.set(create_row_list(from, num));
@@ -92,14 +92,14 @@ struct ActionButtonProps<F: Fn(MouseEvent)> {
id: &'static str,
action: F,
}
fn ActionButton<F>(cx: Context<ActionButtonProps<F>>) -> DomTree
fn ActionButton<'a, F>(cx: Context<'a>, props: &'a ActionButtonProps<F>) -> DomTree<'a>
where
F: Fn(MouseEvent),
{
cx.render(rsx! {
div { class: "col-sm-6 smallpad"
button { class:"btn btn-primary btn-block", r#type: "button", id: "{cx.id}", onclick: {&cx.action},
"{cx.name}"
button { class:"btn btn-primary btn-block", r#type: "button", id: "{props.id}", onclick: {&props.action},
"{props.name}"
}
}
})
@@ -110,12 +110,12 @@ struct RowProps {
row_id: usize,
label: Rc<str>,
}
fn Row<'a>(cx: Context<'a, RowProps>) -> DomTree {
fn Row<'a>(cx: Context<'a>, props: &'a RowProps) -> DomTree<'a> {
cx.render(rsx! {
tr {
td { class:"col-md-1", "{cx.row_id}" }
td { class:"col-md-1", "{props.row_id}" }
td { class:"col-md-1", onclick: move |_| { /* run onselect */ }
a { class: "lbl", "{cx.label}" }
a { class: "lbl", "{props.label}" }
}
td { class: "col-md-1"
a { class: "remove", onclick: move |_| {/* remove */}
+1 -1
View File
@@ -19,7 +19,7 @@ fn main() {
dioxus::desktop::launch(App, |c| c.with_prerendered(content)).unwrap();
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let mut val = use_state(cx, || 0);
cx.render(rsx! {
div {
+1 -1
View File
@@ -20,4 +20,4 @@ fn main() {
dioxus_desktop::WebviewRenderer::run_with_edits(App, (), |c| c, Some(edits)).expect("failed");
}
const App: FC<()> = |cx| todo!();
const App: FC<()> = |cx, props| todo!();
+14 -14
View File
@@ -32,7 +32,7 @@ fn main() {
.expect("failed to launch dioxus app");
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let state = use_state(cx, || Calculator::new());
let clear_display = state.display_value.eq("0");
@@ -79,11 +79,11 @@ struct CalculatorKeyProps<'a> {
onclick: &'a dyn Fn(MouseEvent),
}
fn CalculatorKey<'a, 'r>(cx: Context<'a, CalculatorKeyProps<'r>>) -> DomTree<'a> {
fn CalculatorKey<'a, 'r>(cx: Context<'a>, props: &'a CalculatorKeyProps) -> DomTree<'a> {
cx.render(rsx! {
button {
class: "calculator-key {cx.name}"
onclick: {cx.onclick}
class: "calculator-key {props.name}"
onclick: {props.onclick}
{cx.children()}
}
})
@@ -174,16 +174,16 @@ impl Calculator {
fn handle_keydown(&mut self, evt: KeyboardEvent) {
match evt.key_code() {
KeyCode::Backspace => self.backspace(),
KeyCode::_0 => self.input_digit(0),
KeyCode::_1 => self.input_digit(1),
KeyCode::_2 => self.input_digit(2),
KeyCode::_3 => self.input_digit(3),
KeyCode::_4 => self.input_digit(4),
KeyCode::_5 => self.input_digit(5),
KeyCode::_6 => self.input_digit(6),
KeyCode::_7 => self.input_digit(7),
KeyCode::_8 => self.input_digit(8),
KeyCode::_9 => self.input_digit(9),
KeyCode::Num0 => self.input_digit(0),
KeyCode::Num1 => self.input_digit(1),
KeyCode::Num2 => self.input_digit(2),
KeyCode::Num3 => self.input_digit(3),
KeyCode::Num4 => self.input_digit(4),
KeyCode::Num5 => self.input_digit(5),
KeyCode::Num6 => self.input_digit(6),
KeyCode::Num7 => self.input_digit(7),
KeyCode::Num8 => self.input_digit(8),
KeyCode::Num9 => self.input_digit(9),
KeyCode::Add => self.operator = Some(Operator::Add),
KeyCode::Subtract => self.operator = Some(Operator::Sub),
KeyCode::Divide => self.operator = Some(Operator::Div),
+1 -1
View File
@@ -7,7 +7,7 @@ fn main() {
dioxus::desktop::launch(App, |c| c);
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let mut count = use_state(cx, || 0);
cx.render(rsx! {
+1 -1
View File
@@ -11,7 +11,7 @@ fn main() {
dioxus::desktop::launch(App, |c| c);
}
pub static App: FC<()> = |cx| {
pub static App: FC<()> = |cx, props| {
let state = use_state(cx, PlayerState::new);
let is_playing = state.is_playing();
+11 -11
View File
@@ -32,14 +32,14 @@ use dioxus::prelude::*;
struct NoKeysProps {
data: std::collections::HashMap<u32, String>,
}
static AntipatternNoKeys: FC<NoKeysProps> = |cx| {
static AntipatternNoKeys: FC<NoKeysProps> = |cx, props| {
// WRONG: Make sure to add keys!
rsx!(cx, ul {
{cx.data.iter().map(|(k, v)| rsx!(li { "List item: {v}" }))}
{props.data.iter().map(|(k, v)| rsx!(li { "List item: {v}" }))}
});
// RIGHT: Like this:
rsx!(cx, ul {
{cx.data.iter().map(|(k, v)| rsx!(li { key: "{k}", "List item: {v}" }))}
{props.data.iter().map(|(k, v)| rsx!(li { key: "{k}", "List item: {v}" }))}
})
};
@@ -54,7 +54,7 @@ static AntipatternNoKeys: FC<NoKeysProps> = |cx| {
///
/// Only Component and Fragment nodes are susceptible to this issue. Dioxus mitigates this with components by providing
/// an API for registering shared state without the ContextProvider pattern.
static AntipatternNestedFragments: FC<()> = |cx| {
static AntipatternNestedFragments: FC<()> = |cx, props| {
// Try to avoid heavily nesting fragments
rsx!(cx,
Fragment {
@@ -82,7 +82,7 @@ static AntipatternNestedFragments: FC<()> = |cx| {
/// However, calling set_state will *not* update the current version of state in the component. This should be easy to
/// recognize from the function signature, but Dioxus will not update the "live" version of state. Calling `set_state`
/// merely places a new value in the queue and schedules the component for a future update.
static AntipaternRelyingOnSetState: FC<()> = |cx| {
static AntipaternRelyingOnSetState: FC<()> = |cx, props| {
let (state, set_state) = use_state(cx, || "Hello world").classic();
set_state("New state");
// This will return false! `state` will *still* be "Hello world"
@@ -99,7 +99,7 @@ static AntipaternRelyingOnSetState: FC<()> = |cx| {
/// - All components must start with an uppercase character
///
/// IE: the following component will be rejected when attempted to be used in the rsx! macro
static antipattern_component: FC<()> = |cx| todo!();
static antipattern_component: FC<()> = |cx, props| todo!();
/// Antipattern: Misusing hooks
/// ---------------------------
@@ -120,8 +120,8 @@ static antipattern_component: FC<()> = |cx| todo!();
struct MisuedHooksProps {
should_render_state: bool,
}
static AntipatternMisusedHooks: FC<MisuedHooksProps> = |cx| {
if cx.should_render_state {
static AntipatternMisusedHooks: FC<MisuedHooksProps> = |cx, props| {
if props.should_render_state {
// do not place a hook in the conditional!
// prefer to move it out of the conditional
let (state, set_state) = use_state(cx, || "hello world").classic();
@@ -153,7 +153,7 @@ static AntipatternMisusedHooks: FC<MisuedHooksProps> = |cx| {
/// }
/// }
/// })
static _example: FC<()> = |cx| todo!();
static _example: FC<()> = |cx, props| todo!();
/// Antipattern: publishing components and hooks with all features enabled
/// ----------------------------------------------------------------------
@@ -171,9 +171,9 @@ static _example: FC<()> = |cx| todo!();
///
/// This will only include the `core` dioxus crate which is relatively slim and fast to compile and avoids target-specific
/// libraries.
static __example: FC<()> = |cx| todo!();
static __example: FC<()> = |cx, props| todo!();
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
cx.render(rsx! {
AntipatternNoKeys { data: std::collections::HashMap::new() }
AntipatternNestedFragments {}
+3 -3
View File
@@ -9,7 +9,7 @@
use dioxus::prelude::*;
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
cx.render(rsx! {
div {
Greeting {
@@ -25,10 +25,10 @@ struct GreetingProps {
name: &'static str,
}
static Greeting: FC<GreetingProps> = |cx| {
static Greeting: FC<GreetingProps> = |cx, props| {
cx.render(rsx! {
div {
h1 { "Hello, {cx.name}!" }
h1 { "Hello, {props.name}!" }
p { "Welcome to the Diouxs framework" }
br {}
{cx.children()}
+2 -2
View File
@@ -18,7 +18,7 @@
use dioxus::prelude::*;
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
cx.render(rsx! {
div {
Banner {
@@ -31,7 +31,7 @@ pub static Example: FC<()> = |cx| {
})
};
pub static Banner: FC<()> = |cx| {
pub static Banner: FC<()> = |cx, props| {
cx.render(rsx! {
div {
h1 { "This is a great banner!" }
+9 -9
View File
@@ -16,10 +16,10 @@ use dioxus::prelude::*;
pub struct MyProps {
should_show: bool,
}
pub static Example0: FC<MyProps> = |cx| {
pub static Example0: FC<MyProps> = |cx, props| {
cx.render(rsx! {
div {
{cx.should_show.then(|| rsx!{
{props.should_show.then(|| rsx!{
h1 { "showing the title!" }
})}
}
@@ -39,17 +39,17 @@ pub static Example0: FC<MyProps> = |cx| {
pub struct MyProps1 {
should_show: bool,
}
pub static Example1: FC<MyProps1> = |cx| {
pub static Example1: FC<MyProps1> = |cx, props| {
cx.render(rsx! {
div {
// With matching
{match cx.should_show {
{match props.should_show {
true => cx.render(rsx!(div {"it is true!"})),
false => rsx!(cx, div {"it is false!"}),
}}
// or with just regular conditions
{if cx.should_show {
{if props.should_show {
rsx!(cx, div {"it is true!"})
} else {
rsx!(cx, div {"it is false!"})
@@ -57,7 +57,7 @@ pub static Example1: FC<MyProps1> = |cx| {
// or with optional chaining
{
cx.should_show
props.should_show
.then(|| rsx!(cx, div {"it is false!"}))
.unwrap_or_else(|| rsx!(cx, div {"it is false!"}))
}
@@ -77,10 +77,10 @@ pub enum Color {
pub struct MyProps2 {
color: Color,
}
pub static Example2: FC<MyProps2> = |cx| {
pub static Example2: FC<MyProps2> = |cx, props| {
cx.render(rsx! {
div {
{match cx.color {
{match props.color {
Color::Green => rsx!(cx, div {"it is Green!"}),
Color::Yellow => rsx!(cx, div {"it is Yellow!"}),
Color::Red => rsx!(cx, div {"it is Red!"}),
@@ -89,7 +89,7 @@ pub static Example2: FC<MyProps2> = |cx| {
})
};
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
let should_show = use_state(cx, || false);
let mut color_index = use_state(cx, || 0);
let color = match *color_index % 2 {
+3 -3
View File
@@ -1,7 +1,7 @@
use dioxus::prelude::*;
fn main() {}
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
cx.render(rsx! {
div {
@@ -10,7 +10,7 @@ pub static Example: FC<()> = |cx| {
};
// A controlled component:
static ControlledSelect: FC<()> = |cx| {
static ControlledSelect: FC<()> = |cx, props| {
let value = use_state(cx, || String::from("Grapefruit"));
cx.render(rsx! {
select { value: "{value}", onchange: move |evt| value.set(evt.value()),
@@ -23,7 +23,7 @@ static ControlledSelect: FC<()> = |cx| {
};
// TODO - how do uncontrolled things work?
static UncontrolledSelect: FC<()> = |cx| {
static UncontrolledSelect: FC<()> = |cx, props| {
let value = use_state(cx, || String::new());
cx.render(rsx! {
+1 -1
View File
@@ -11,7 +11,7 @@
use dioxus::prelude::*;
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
cx.render(rsx! {
div {
custom_element {
+1 -1
View File
@@ -5,4 +5,4 @@
use dioxus::prelude::*;
pub static Example: FC<()> = |cx| cx.render(rsx! { Fragment {} });
pub static Example: FC<()> = |cx, props| cx.render(rsx! { Fragment {} });
+6 -6
View File
@@ -23,14 +23,14 @@ 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.
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
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
static App1: FC<()> = |cx| {
static App1: FC<()> = |cx, props| {
let data = match get_data() {
Some(data) => data,
None => return None,
@@ -46,7 +46,7 @@ static App1: FC<()> = |cx| {
/// a user is logged in.
///
/// Dioxus will throw an error in the console if the None-path is ever taken.
static App2: FC<()> = |cx| {
static App2: FC<()> = |cx, props| {
let data = get_data()?;
cx.render(rsx!( div { "{data}" } ))
};
@@ -54,14 +54,14 @@ static App2: FC<()> = |cx| {
/// This is top-tier error handling since it displays a failure state.
///
/// However, the error is lacking in context.
static App3: FC<()> = |cx| match get_data() {
static App3: FC<()> = |cx, props| 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 short-circuit the match-based error handling with `.ok()` which converts
/// a Result<T, V> into an Option<T> and lets you
static App4: FC<()> = |cx| {
static App4: FC<()> = |cx, props| {
let data = get_data_err().ok()?;
cx.render(rsx!( div { "{data}" } ))
};
@@ -69,7 +69,7 @@ static App4: FC<()> = |cx| {
/// This is great error handling since it displays a failure state... with context!
///
/// Hopefully you never need to disply a screen like this. It's rather bad taste
static App5: FC<()> = |cx| match get_data_err() {
static App5: FC<()> = |cx, props| match get_data_err() {
Ok(data) => cx.render(rsx!( div { "{data}" } )),
Err(c) => cx.render(rsx!( div { "Failed to load data: {c}" } )),
};
+4 -4
View File
@@ -11,7 +11,7 @@
use dioxus::prelude::*;
// Returning multiple elements with rsx! or html!
static App1: FC<()> = |cx| {
static App1: FC<()> = |cx, props| {
cx.render(rsx! {
h1 { }
h2 { }
@@ -20,7 +20,7 @@ static App1: FC<()> = |cx| {
};
// Using the Fragment component
static App2: FC<()> = |cx| {
static App2: FC<()> = |cx, props| {
cx.render(rsx! {
Fragment {
div {}
@@ -31,7 +31,7 @@ static App2: FC<()> = |cx| {
};
// Using the `fragment` method on the NodeFactory
static App3: FC<()> = |cx| {
static App3: FC<()> = |cx, props| {
cx.render(LazyNodes::new(move |fac| {
fac.fragment_from_iter([
fac.text(format_args!("A")),
@@ -42,7 +42,7 @@ static App3: FC<()> = |cx| {
}))
};
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
cx.render(rsx! {
App1 {}
App2 {}
+1 -1
View File
@@ -19,7 +19,7 @@ h1 {color: blue;}
p {color: red;}
"#;
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
cx.render(rsx! {
head { style { "{STYLE}" } }
body {
+2 -2
View File
@@ -10,7 +10,7 @@
use dioxus::prelude::*;
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
cx.render(rsx! {
head {
style: { background_color: "powderblue" }
@@ -29,7 +29,7 @@ pub static Example: FC<()> = |cx| {
// .... technically the rsx! macro is slightly broken at the moment and alows styles not wrapped in style {}
// I haven't noticed any name collisions yet, and am tentatively leaving this behavior in..
// Don't rely on it.
static Example2: FC<()> = |cx| {
static Example2: FC<()> = |cx, props| {
cx.render(rsx! {
div { color: "red"
"hello world!"
+1 -1
View File
@@ -12,7 +12,7 @@
use dioxus::prelude::*;
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
let example_data = use_state(cx, || 0);
let v = (0..10).map(|f| {
+4 -4
View File
@@ -7,7 +7,7 @@
use dioxus::prelude::*;
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
cx.render(rsx! {
ButtonList {}
NonUpdatingEvents {}
@@ -16,7 +16,7 @@ pub static Example: FC<()> = |cx| {
};
/// We can use `set_name` in multiple closures; the closures automatically *copy* the reference to set_name.
static ButtonList: FC<()> = |cx| {
static ButtonList: FC<()> = |cx, props| {
let name = use_state(cx, || "...?");
let names = ["jack", "jill", "john", "jane"]
@@ -33,7 +33,7 @@ static ButtonList: FC<()> = |cx| {
/// This shows how listeners may be without a visible change in the display.
/// Check the console.
static NonUpdatingEvents: FC<()> = |cx| {
static NonUpdatingEvents: FC<()> = |cx, props| {
rsx!(cx, div {
button {
onclick: move |_| log::info!("Did not cause any updates!")
@@ -42,7 +42,7 @@ static NonUpdatingEvents: FC<()> = |cx| {
})
};
static DisablePropogation: FC<()> = |cx| {
static DisablePropogation: FC<()> = |cx, props| {
rsx!(cx,
div {
onclick: move |_| log::info!("event propogated to the div!")
+9 -9
View File
@@ -21,7 +21,7 @@ use dioxus::prelude::*;
// By default, components with no props are always memoized.
// A props of () is considered empty.
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
cx.render(rsx! {
div { "100% memoized!" }
})
@@ -35,9 +35,9 @@ pub struct MyProps1 {
name: String,
}
pub static Example1: FC<MyProps1> = |cx| {
pub static Example1: FC<MyProps1> = |cx, props| {
cx.render(rsx! {
div { "100% memoized! {cx.name}" }
div { "100% memoized! {props.name}" }
})
};
@@ -49,9 +49,9 @@ pub struct MyProps2 {
name: std::rc::Rc<str>,
}
pub static Example2: FC<MyProps2> = |cx| {
pub static Example2: FC<MyProps2> = |cx, props| {
cx.render(rsx! {
div { "100% memoized! {cx.name}" }
div { "100% memoized! {props.name}" }
})
};
@@ -63,9 +63,9 @@ pub struct MyProps3<'a> {
// We need to manually specify a lifetime that ensures props and scope (the component's state) share the same lifetime.
// Using the `pub static Example: FC<()>` pattern _will_ specify a lifetime, but that lifetime will be static which might
// not exactly be what you want
fn Example3<'a>(cx: Context<'a, MyProps3<'a>>) -> DomTree {
fn Example3<'a>(cx: Context<'a>, props: &'a MyProps3) -> DomTree<'a> {
cx.render(rsx! {
div { "Not memoized! {cx.name}" }
div { "Not memoized! {props.name}" }
})
}
@@ -77,8 +77,8 @@ pub struct MyProps4<'a> {
}
// We need to manually specify a lifetime that ensures props and scope (the component's state) share the same lifetime.
fn Example4<'a>(cx: Context<'a, MyProps4<'a>>) -> DomTree {
fn Example4<'a>(cx: Context<'a>, props: &'a MyProps4) -> DomTree<'a> {
cx.render(rsx! {
div { "Not memoized!", onclick: move |_| (cx.onhandle)() }
div { "Not memoized!", onclick: move |_| (props.onhandle)() }
})
}
+1 -1
View File
@@ -1,7 +1,7 @@
use dioxus::prelude::*;
fn main() {}
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
let p = 10;
cx.render(rsx! {
+1 -1
View File
@@ -1,7 +1,7 @@
use dioxus::prelude::*;
fn main() {}
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
cx.render(rsx! {
div {
+5 -5
View File
@@ -9,7 +9,7 @@
use dioxus::prelude::*;
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
let props = MyProps {
count: 0,
live: true,
@@ -27,12 +27,12 @@ pub struct MyProps {
name: &'static str,
}
pub static Example1: FC<MyProps> = |cx| {
pub static Example1: FC<MyProps> = |cx, MyProps { count, live, name }| {
cx.render(rsx! {
div {
h1 { "Hello, {cx.name}"}
h3 {"Are we alive? {cx.live}"}
p {"Count is {cx.count}"}
h1 { "Hello, {name}"}
h3 {"Are we alive? {live}"}
p {"Count is {count}"}
{ cx.children() }
}
})
+1 -1
View File
@@ -1,7 +1,7 @@
use dioxus::prelude::*;
fn main() {}
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
cx.render(rsx! {
div {
+7 -2
View File
@@ -14,12 +14,17 @@ struct DogApi {
}
const ENDPOINT: &str = "https://dog.ceo/api/breeds/image/random";
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
let doggo = use_suspense(
cx,
|| surf::get(ENDPOINT).recv_json::<DogApi>(),
|cx, res| match res {
Ok(res) => rsx!(cx, img { src: "{res.message}" }),
Ok(res) => rsx!(
cx,
img {
src: "{res.message}"
}
),
Err(_) => rsx!(cx, div { "No doggos for you :(" }),
},
);
+1 -1
View File
@@ -24,7 +24,7 @@
use dioxus::prelude::*;
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
let count = use_state(cx, || 0);
let mut direction = use_state(cx, || 1);
+1 -1
View File
@@ -1,6 +1,6 @@
use dioxus::prelude::*;
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
cx.render(rsx! {
div {
+2 -2
View File
@@ -1,7 +1,7 @@
use dioxus::prelude::*;
use dioxus::ssr;
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
let as_string = use_state(cx, || {
// Currently, SSR is only supported for whole VirtualDOMs
// This is an easy/low hanging fruit to improve upon
@@ -15,7 +15,7 @@ pub static Example: FC<()> = |cx| {
})
};
static SomeApp: FC<()> = |cx| {
static SomeApp: FC<()> = |cx, props| {
cx.render(rsx! {
div { style: {background_color: "blue"}
h1 {"Some amazing app or component"}
+4 -3
View File
@@ -49,7 +49,7 @@ const NONE_ELEMENT: Option<()> = None;
use baller::Baller;
use dioxus::prelude::*;
pub static Example: FC<()> = |cx| {
pub static Example: FC<()> = |cx, props| {
let formatting = "formatting!";
let formatting_tuple = ("a", "b");
let lazy_fmt = format_args!("lazily formatted text");
@@ -180,10 +180,11 @@ pub static Example: FC<()> = |cx| {
mod baller {
use super::*;
#[derive(PartialEq, Props)]
pub struct BallerProps {}
/// This component totally balls
pub fn Baller(cx: Context<()>) -> DomTree {
pub fn Baller<'a>(cx: Context<'a>, props: &BallerProps) -> DomTree<'a> {
todo!()
}
}
@@ -194,7 +195,7 @@ pub struct TallerProps {
}
/// This component is taller than most :)
pub fn Taller(cx: Context<TallerProps>) -> DomTree {
pub fn Taller<'a>(cx: Context<'a>, props: &'a TallerProps) -> DomTree<'a> {
let b = true;
todo!()
}
+5 -5
View File
@@ -11,7 +11,7 @@ fn main() {}
use dioxus::prelude::*;
use std::rc::Rc;
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let (selection, set_selection) = use_state(cx, || None as Option<usize>).classic();
let body = match selection {
@@ -33,7 +33,7 @@ struct ScrollSelectorProps<'a> {
onselect: &'a dyn Fn(Option<usize>),
}
fn ScrollSelector<'a>(cx: Context<'a, ScrollSelectorProps>) -> DomTree<'a> {
fn ScrollSelector<'a>(cx: Context<'a>, props: &'a ScrollSelectorProps) -> DomTree<'a> {
let selection_list = (&REFERENCES).iter().enumerate().map(|(id, _)| {
rsx! {
li {
@@ -47,7 +47,7 @@ fn ScrollSelector<'a>(cx: Context<'a, ScrollSelectorProps>) -> DomTree<'a> {
ul {
{selection_list}
button {
onclick: move |_| (cx.onselect)(Some(10))
onclick: move |_| (props.onselect)(Some(10))
}
}
}
@@ -59,8 +59,8 @@ struct ReferenceItemProps {
selected: usize,
}
static ReferenceItem: FC<ReferenceItemProps> = |cx| {
let (caller, name, code) = REFERENCES[cx.selected];
static ReferenceItem: FC<ReferenceItemProps> = |cx, props| {
let (caller, name, code) = REFERENCES[props.selected];
// Create the component using the factory API directly
let caller_node = LazyNodes::new(move |f| f.component(caller, (), None, &[]));
+6 -6
View File
@@ -15,7 +15,7 @@ fn main() {
dioxus::desktop::launch(App, |c| c);
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let slides = use_state(cx, SlideController::new);
let slide = match slides.slide_id {
@@ -70,7 +70,7 @@ impl SlideController {
}
}
const Title: FC<()> = |cx| {
const Title: FC<()> = |cx, props| {
cx.render(rsx! {
div {
h1 { "Title" }
@@ -78,7 +78,7 @@ const Title: FC<()> = |cx| {
}
})
};
const Slide1: FC<()> = |cx| {
const Slide1: FC<()> = |cx, props| {
cx.render(rsx! {
div {
h1 { "Slide1" }
@@ -86,7 +86,7 @@ const Slide1: FC<()> = |cx| {
}
})
};
const Slide2: FC<()> = |cx| {
const Slide2: FC<()> = |cx, props| {
cx.render(rsx! {
div {
h1 { "Slide2" }
@@ -94,7 +94,7 @@ const Slide2: FC<()> = |cx| {
}
})
};
const Slide3: FC<()> = |cx| {
const Slide3: FC<()> = |cx, props| {
cx.render(rsx! {
div {
h1 { "Slide3" }
@@ -102,7 +102,7 @@ const Slide3: FC<()> = |cx| {
}
})
};
const End: FC<()> = |cx| {
const End: FC<()> = |cx, props| {
cx.render(rsx! {
div {
h1 { "End" }
+2 -2
View File
@@ -9,7 +9,7 @@ fn main() {
println!("{}", ssr::render_vdom(&vdom, |c| c));
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
cx.render(rsx!(
div {
h1 { "Title" }
@@ -21,6 +21,6 @@ static App: FC<()> = |cx| {
struct MyProps<'a> {
text: &'a str,
}
fn App2<'a>(cx: Context<'a, MyProps>) -> DomTree<'a> {
fn App2<'a>(cx: Context<'a>, props: &'a MyProps) -> DomTree<'a> {
None
}
+6 -6
View File
@@ -14,7 +14,7 @@ fn main() {
const STYLE: &str = "body {overflow:hidden;}";
pub static App: FC<()> = |cx| {
pub static App: FC<()> = |cx, props| {
cx.render(rsx!(
div { class: "overflow-hidden"
style { "{STYLE}" }
@@ -30,7 +30,7 @@ pub static App: FC<()> = |cx| {
))
};
pub static Header: FC<()> = |cx| {
pub static Header: FC<()> = |cx, props| {
cx.render(rsx! {
div {
header { class: "text-gray-400 bg-gray-900 body-font"
@@ -56,7 +56,7 @@ pub static Header: FC<()> = |cx| {
})
};
pub static Hero: FC<()> = |cx| {
pub static Hero: FC<()> = |cx, props| {
//
cx.render(rsx! {
section{ class: "text-gray-400 bg-gray-900 body-font"
@@ -94,7 +94,7 @@ pub static Hero: FC<()> = |cx| {
}
})
};
pub static Entry: FC<()> = |cx| {
pub static Entry: FC<()> = |cx, props| {
//
cx.render(rsx! {
section{ class: "text-gray-400 bg-gray-900 body-font"
@@ -107,7 +107,7 @@ pub static Entry: FC<()> = |cx| {
})
};
pub static StacksIcon: FC<()> = |cx| {
pub static StacksIcon: FC<()> = |cx, props| {
cx.render(rsx!(
svg {
// xmlns: "http://www.w3.org/2000/svg"
@@ -122,7 +122,7 @@ pub static StacksIcon: FC<()> = |cx| {
}
))
};
pub static RightArrowIcon: FC<()> = |cx| {
pub static RightArrowIcon: FC<()> = |cx, props| {
cx.render(rsx!(
svg {
fill: "none"
+3 -3
View File
@@ -17,7 +17,7 @@ h1 {color: blue;}
p {color: red;}
"#;
const Example: FC<()> = |cx| {
const Example: FC<()> = |cx, props| {
cx.render(rsx! {
Fragment {
Fragment {
@@ -38,7 +38,7 @@ const Example: FC<()> = |cx| {
})
};
const Child: FC<()> = |cx| {
const Child: FC<()> = |cx, props| {
cx.render(rsx!(
h1 {"1" }
h1 {"2" }
@@ -48,7 +48,7 @@ const Child: FC<()> = |cx| {
};
// this is a bad case that hurts our subtree memoization :(
const AbTest: FC<()> = |cx| {
const AbTest: FC<()> = |cx, props| {
if 1 == 2 {
cx.render(rsx!(
h1 {"1"}
+2 -3
View File
@@ -22,7 +22,7 @@ pub struct TodoItem {
}
const STYLE: &str = include_str!("./_examples/todomvc/style.css");
const App: FC<()> = |cx| {
const App: FC<()> = |cx, props| {
let draft = use_state(cx, || "".to_string());
let todos = use_state(cx, || HashMap::<u32, Rc<TodoItem>>::new());
let filter = use_state(cx, || FilterState::All);
@@ -87,8 +87,7 @@ pub struct TodoEntryProps {
todo: std::rc::Rc<TodoItem>,
}
pub fn TodoEntry(cx: Context<TodoEntryProps>) -> DomTree {
let TodoEntryProps { todo } = *cx;
pub fn TodoEntry<'a>(cx: Context<'a>, TodoEntryProps { todo }: &'a TodoEntryProps) -> DomTree<'a> {
let is_editing = use_state(cx, || false);
let contents = "";
+4 -4
View File
@@ -19,7 +19,7 @@ fn main() {
dioxus::web::launch(App, |c| c);
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let mut rng = SmallRng::from_entropy();
let rows = (0..1_000).map(|f| {
let label = Label::new(&mut rng);
@@ -45,11 +45,11 @@ struct RowProps {
row_id: usize,
label: Label,
}
fn Row<'a>(cx: Context<'a, RowProps>) -> DomTree {
let [adj, col, noun] = cx.label.0;
fn Row<'a>(cx: Context<'a>, props: &'a RowProps) -> DomTree<'a> {
let [adj, col, noun] = props.label.0;
cx.render(rsx! {
tr {
td { class:"col-md-1", "{cx.row_id}" }
td { class:"col-md-1", "{props.row_id}" }
td { class:"col-md-1", onclick: move |_| { /* run onselect */ }
a { class: "lbl", "{adj}" "{col}" "{noun}" }
}
+4 -4
View File
@@ -17,7 +17,7 @@ fn main() -> anyhow::Result<()> {
dioxus::desktop::launch(App, |c| c)
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let state = use_state(cx, || String::from("hello"));
let clear_text = state == "hello";
@@ -37,11 +37,11 @@ struct CalculatorKeyProps<'a> {
onclick: &'a dyn Fn(MouseEvent),
}
fn CalculatorKey<'a, 'r>(cx: Context<'a, CalculatorKeyProps<'r>>) -> DomTree<'a> {
fn CalculatorKey<'a>(cx: Context<'a>, props: &'a CalculatorKeyProps) -> DomTree<'a> {
cx.render(rsx! {
button {
class: "calculator-key {cx.name}"
onclick: {cx.onclick}
class: "calculator-key {props.name}"
onclick: {props.onclick}
{cx.children()}
}
})
+1 -1
View File
@@ -16,7 +16,7 @@ fn main() {
dioxus::web::launch(App, |c| c);
}
static App: FC<()> = |cx| {
static App: FC<()> = |cx, props| {
let mut count = use_state(cx, || 0);
cx.render(rsx! {