wip: move examples around
This commit is contained in:
1 parent
d298b626d3
commit
1e6e5e611b
86 files changed
+160
-216
No files matched your search
Vendored
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
// "rust-analyzer.cargo.allFeatures": true
|
"rust-analyzer.cargo.allFeatures": true
|
||||||
}
|
}
|
||||||
@@ -79,7 +79,6 @@ members = [
|
|||||||
"packages/ssr",
|
"packages/ssr",
|
||||||
"packages/desktop",
|
"packages/desktop",
|
||||||
"packages/mobile",
|
"packages/mobile",
|
||||||
"packages/webview-client",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -114,12 +114,13 @@ const APP: FC<()> = |(cx, _)| {
|
|||||||
struct CalculatorKeyProps<'a> {
|
struct CalculatorKeyProps<'a> {
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
onclick: &'a dyn Fn(MouseEvent),
|
onclick: &'a dyn Fn(MouseEvent),
|
||||||
|
children: ScopeChildren<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn CalculatorKey<'a>((cx, props): Scope<'a, CalculatorKeyProps>) -> Element<'a> {
|
fn CalculatorKey<'a>((cx, props): Scope<'a, CalculatorKeyProps<'a>>) -> Element {
|
||||||
rsx!(cx, button {
|
rsx!(cx, button {
|
||||||
class: "calculator-key {props.name}"
|
class: "calculator-key {props.name}"
|
||||||
onclick: {props.onclick}
|
onclick: {props.onclick}
|
||||||
{cx.children()}
|
{&props.children}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+11
-9
@@ -46,7 +46,8 @@ static App: FC<()> = |(cx, props)| {
|
|||||||
});
|
});
|
||||||
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
div { style: { width: "400px", height: "400px", position: "relative", background: "yellow" }
|
div {
|
||||||
|
width: "400px", height: "400px", position: "relative", background: "yellow"
|
||||||
button { "reset", onclick: move |_| {} }
|
button { "reset", onclick: move |_| {} }
|
||||||
Horsey { pos: *p1, "horsey 1" }
|
Horsey { pos: *p1, "horsey 1" }
|
||||||
Horsey { pos: *p2, "horsey 2" }
|
Horsey { pos: *p2, "horsey 2" }
|
||||||
@@ -54,18 +55,19 @@ static App: FC<()> = |(cx, props)| {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(PartialEq, Props)]
|
#[derive(Props)]
|
||||||
struct HorseyProps {
|
struct HorseyProps<'a> {
|
||||||
pos: i32,
|
pos: i32,
|
||||||
|
children: ScopeChildren<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
static Horsey: FC<HorseyProps> = |(cx, props)| {
|
fn Horsey<'a>((cx, props): Scope<'a, HorseyProps<'a>>) -> Element {
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
div {
|
|
||||||
button { "pause" }
|
|
||||||
div {
|
div {
|
||||||
{cx.children()}
|
button { "pause" }
|
||||||
|
div {
|
||||||
|
{&props.children}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
})
|
||||||
};
|
}
|
||||||
+5
-5
@@ -20,12 +20,12 @@ pub struct Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static App: FC<()> = |(cx, _)| {
|
static App: FC<()> = |(cx, _)| {
|
||||||
let clients = use_ref(cx, || vec![] as Vec<Client>);
|
let mut clients = use_ref(cx, || vec![] as Vec<Client>);
|
||||||
let scene = use_state(cx, || Scene::ClientsList);
|
let mut scene = use_state(cx, || Scene::ClientsList);
|
||||||
|
|
||||||
let firstname = use_state(cx, || String::new());
|
let mut firstname = use_state(cx, || String::new());
|
||||||
let lastname = use_state(cx, || String::new());
|
let mut lastname = use_state(cx, || String::new());
|
||||||
let description = use_state(cx, || String::new());
|
let mut description = use_state(cx, || String::new());
|
||||||
|
|
||||||
let scene = match *scene {
|
let scene = match *scene {
|
||||||
Scene::ClientsList => {
|
Scene::ClientsList => {
|
||||||
|
|||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -34,11 +34,11 @@ pub type Todos = HashMap<u32, TodoItem>;
|
|||||||
|
|
||||||
pub static App: FC<()> = |(cx, _)| {
|
pub static App: FC<()> = |(cx, _)| {
|
||||||
// Share our TodoList to the todos themselves
|
// Share our TodoList to the todos themselves
|
||||||
use_provide_state(cx, || Todos::new());
|
use_provide_state(cx, Todos::new);
|
||||||
|
|
||||||
// Save state for the draft, filter
|
// Save state for the draft, filter
|
||||||
let mut draft = use_state(cx, || "".to_string());
|
let draft = use_state(cx, || "".to_string());
|
||||||
let mut filter = use_state(cx, || FilterState::All);
|
let filter = use_state(cx, || FilterState::All);
|
||||||
let mut todo_id = use_state(cx, || 0);
|
let mut todo_id = use_state(cx, || 0);
|
||||||
|
|
||||||
// Consume the todos
|
// Consume the todos
|
||||||
@@ -95,7 +95,7 @@ pub static App: FC<()> = |(cx, _)| {
|
|||||||
placeholder: "What needs to be done?"
|
placeholder: "What needs to be done?"
|
||||||
value: "{draft}"
|
value: "{draft}"
|
||||||
autofocus: "true"
|
autofocus: "true"
|
||||||
oninput: move |evt| draft.set(evt.value.clone())
|
oninput: move |evt| draft.set(evt.value)
|
||||||
onkeydown: move |evt| {
|
onkeydown: move |evt| {
|
||||||
if evt.key == "Enter" {
|
if evt.key == "Enter" {
|
||||||
submit_todo();
|
submit_todo();
|
||||||
@@ -150,7 +150,9 @@ pub fn TodoEntry((cx, props): Scope<TodoEntryProps>) -> Element {
|
|||||||
div { class: "view"
|
div { class: "view"
|
||||||
input { class: "toggle" r#type: "checkbox" id: "cbg-{todo.id}" checked: "{todo.checked}"
|
input { class: "toggle" r#type: "checkbox" id: "cbg-{todo.id}" checked: "{todo.checked}"
|
||||||
onchange: move |evt| {
|
onchange: move |evt| {
|
||||||
todos.write().get_mut(&props.id).map(|todo| todo.checked = evt.value.parse().unwrap());
|
if let Some(todo) = todos.write().get_mut(&props.id) {
|
||||||
|
todo.checked = evt.value.parse().unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +163,9 @@ pub fn TodoEntry((cx, props): Scope<TodoEntryProps>) -> Element {
|
|||||||
{is_editing.then(|| rsx!{
|
{is_editing.then(|| rsx!{
|
||||||
input { value: "{todo.contents}"
|
input { value: "{todo.contents}"
|
||||||
oninput: move |evt| {
|
oninput: move |evt| {
|
||||||
todos.write().get_mut(&props.id).map(|todo| todo.contents = evt.value.clone());
|
if let Some(todo) = todos.write().get_mut(&props.id) {
|
||||||
|
todo.contents = evt.value
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
@@ -10,11 +10,11 @@ fn main() {
|
|||||||
type RowList = im_rc::HashMap<usize, Rc<str>, FxBuildHasher>;
|
type RowList = im_rc::HashMap<usize, Rc<str>, FxBuildHasher>;
|
||||||
|
|
||||||
static App: FC<()> = |(cx, _props)| {
|
static App: FC<()> = |(cx, _props)| {
|
||||||
let items = use_state(cx, || RowList::default());
|
let mut items = use_state(cx, || RowList::default());
|
||||||
|
|
||||||
let create_rendered_rows = move |from, num| move |_| items.set(create_row_list(from, num));
|
let create_rendered_rows = move |from, num| move |_| items.set(create_row_list(from, num));
|
||||||
|
|
||||||
let append_1_000_rows =
|
let mut append_1_000_rows =
|
||||||
move |_| items.set(create_row_list(items.len(), 1000).union((*items).clone()));
|
move |_| items.set(create_row_list(items.len(), 1000).union((*items).clone()));
|
||||||
|
|
||||||
let update_every_10th_row = move |_| {
|
let update_every_10th_row = move |_| {
|
||||||
|
|||||||
@@ -74,14 +74,15 @@ static App: FC<()> = |(cx, props)| {
|
|||||||
struct CalculatorKeyProps<'a> {
|
struct CalculatorKeyProps<'a> {
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
onclick: &'a dyn Fn(MouseEvent),
|
onclick: &'a dyn Fn(MouseEvent),
|
||||||
|
children: ScopeChildren<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn CalculatorKey<'a>((cx, props): Scope<'a, CalculatorKeyProps>) -> Element<'a> {
|
fn CalculatorKey<'a>((cx, props): Scope<'a, CalculatorKeyProps<'a>>) -> Element<'a> {
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
button {
|
button {
|
||||||
class: "calculator-key {props.name}"
|
class: "calculator-key {props.name}"
|
||||||
onclick: {props.onclick}
|
onclick: {props.onclick}
|
||||||
{cx.children()}
|
{&props.children}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_router::{use_router, Link, Routable};
|
use dioxus::router::Router;
|
||||||
|
|
||||||
fn main() {
|
|
||||||
dbg!(App as *const fn());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Clone)]
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
pub enum Route {
|
pub enum Route {
|
||||||
@@ -86,3 +82,5 @@ impl Routable for Route {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
@@ -162,13 +162,13 @@ pub static Example: FC<()> = |(cx, props)| {
|
|||||||
|
|
||||||
// Can pass in props directly as an expression
|
// Can pass in props directly as an expression
|
||||||
{{
|
{{
|
||||||
let props = TallerProps {a: "hello"};
|
let props = TallerProps {a: "hello", children: Default::default()};
|
||||||
rsx!(Taller { ..props })
|
rsx!(Taller { ..props })
|
||||||
}}
|
}}
|
||||||
|
|
||||||
// Spreading can also be overridden manually
|
// Spreading can also be overridden manually
|
||||||
Taller {
|
Taller {
|
||||||
..TallerProps { a: "ballin!" }
|
..TallerProps { a: "ballin!", children: Default::default() }
|
||||||
a: "not ballin!"
|
a: "not ballin!"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ pub static Example: FC<()> = |(cx, props)| {
|
|||||||
|
|
||||||
mod baller {
|
mod baller {
|
||||||
use super::*;
|
use super::*;
|
||||||
#[derive(PartialEq, Props)]
|
#[derive(Props, PartialEq)]
|
||||||
pub struct BallerProps {}
|
pub struct BallerProps {}
|
||||||
|
|
||||||
/// This component totally balls
|
/// This component totally balls
|
||||||
@@ -189,13 +189,16 @@ mod baller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Props)]
|
#[derive(Props)]
|
||||||
pub struct TallerProps {
|
pub struct TallerProps<'a> {
|
||||||
a: &'static str,
|
a: &'static str,
|
||||||
|
|
||||||
|
#[builder(default)]
|
||||||
|
children: ScopeChildren<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This component is taller than most :)
|
/// This component is taller than most :)
|
||||||
pub fn Taller(_: Scope<TallerProps>) -> Element {
|
pub fn Taller<'a>(_: Scope<'a, TallerProps<'a>>) -> Element {
|
||||||
let b = true;
|
let b = true;
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -119,14 +119,14 @@ pub static Entry: FC<()> = |(cx, props)| {
|
|||||||
pub static StacksIcon: FC<()> = |(cx, props)| {
|
pub static StacksIcon: FC<()> = |(cx, props)| {
|
||||||
cx.render(rsx!(
|
cx.render(rsx!(
|
||||||
svg {
|
svg {
|
||||||
// xmlns: "http://www.w3.org/2000/svg"
|
xmlns: "http://www.w3.org/2000/svg"
|
||||||
fill: "none"
|
fill: "none"
|
||||||
stroke: "currentColor"
|
stroke: "currentColor"
|
||||||
stroke_linecap: "round"
|
stroke_linecap: "round"
|
||||||
stroke_linejoin: "round"
|
stroke_linejoin: "round"
|
||||||
stroke_width: "2"
|
stroke_width: "2"
|
||||||
// class: "w-10 h-10 text-white p-2 bg-indigo-500 rounded-full"
|
class: "w-10 h-10 text-white p-2 bg-indigo-500 rounded-full"
|
||||||
viewBox: "0 0 24 24"
|
view_box: "0 0 24 24"
|
||||||
path { d: "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"}
|
path { d: "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"}
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
@@ -139,8 +139,8 @@ pub static RightArrowIcon: FC<()> = |(cx, props)| {
|
|||||||
stroke_linecap: "round"
|
stroke_linecap: "round"
|
||||||
stroke_linejoin: "round"
|
stroke_linejoin: "round"
|
||||||
stroke_width: "2"
|
stroke_width: "2"
|
||||||
// class: "w-4 h-4 ml-1"
|
class: "w-4 h-4 ml-1"
|
||||||
viewBox: "0 0 24 24"
|
view_box: "0 0 24 24"
|
||||||
path { d: "M5 12h14M12 5l7 7-7 7"}
|
path { d: "M5 12h14M12 5l7 7-7 7"}
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
@@ -117,7 +117,7 @@ pub static StacksIcon: FC<()> = |(cx, props)| {
|
|||||||
stroke_linejoin: "round"
|
stroke_linejoin: "round"
|
||||||
stroke_width: "2"
|
stroke_width: "2"
|
||||||
class: "w-10 h-10 text-white p-2 bg-indigo-500 rounded-full"
|
class: "w-10 h-10 text-white p-2 bg-indigo-500 rounded-full"
|
||||||
viewBox: "0 0 24 24"
|
view_box: "0 0 24 24"
|
||||||
path { d: "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"}
|
path { d: "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"}
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
@@ -131,7 +131,7 @@ pub static RightArrowIcon: FC<()> = |(cx, props)| {
|
|||||||
stroke_linejoin: "round"
|
stroke_linejoin: "round"
|
||||||
stroke_width: "2"
|
stroke_width: "2"
|
||||||
class: "w-4 h-4 ml-1"
|
class: "w-4 h-4 ml-1"
|
||||||
viewBox: "0 0 24 24"
|
view_box: "0 0 24 24"
|
||||||
path { d: "M5 12h14M12 5l7 7-7 7"}
|
path { d: "M5 12h14M12 5l7 7-7 7"}
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
|
|||||||
+5
-5
@@ -23,9 +23,9 @@ pub struct TodoItem {
|
|||||||
|
|
||||||
const STYLE: &str = include_str!("./assets/todomvc.css");
|
const STYLE: &str = include_str!("./assets/todomvc.css");
|
||||||
const App: FC<()> = |(cx, props)| {
|
const App: FC<()> = |(cx, props)| {
|
||||||
let draft = use_state(cx, || "".to_string());
|
let mut draft = use_state(cx, || "".to_string());
|
||||||
let todos = use_state(cx, || HashMap::<u32, Rc<TodoItem>>::new());
|
let mut todos = use_state(cx, || HashMap::<u32, Rc<TodoItem>>::new());
|
||||||
let filter = use_state(cx, || FilterState::All);
|
let mut filter = use_state(cx, || FilterState::All);
|
||||||
|
|
||||||
let todolist = todos
|
let todolist = todos
|
||||||
.iter()
|
.iter()
|
||||||
@@ -86,8 +86,8 @@ pub struct TodoEntryProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn TodoEntry((cx, props): Scope<TodoEntryProps>) -> Element {
|
pub fn TodoEntry((cx, props): Scope<TodoEntryProps>) -> Element {
|
||||||
let is_editing = use_state(cx, || false);
|
let mut is_editing = use_state(cx, || false);
|
||||||
let contents = use_state(cx, || String::from(""));
|
let mut contents = use_state(cx, || String::from(""));
|
||||||
let todo = &props.todo;
|
let todo = &props.todo;
|
||||||
|
|
||||||
rsx!(cx, li {
|
rsx!(cx, li {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ static App: FC<()> = |(cx, props)| {
|
|||||||
},
|
},
|
||||||
|cx, props| {
|
|cx, props| {
|
||||||
//
|
//
|
||||||
rsx!(cx, WeatherDisplay {})
|
rsx!(WeatherDisplay {})
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -22,7 +22,6 @@ static App: FC<()> = |(cx, props)| {
|
|||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
div {
|
div {
|
||||||
h1 { "Hifive counter: {count}" }
|
h1 { "Hifive counter: {count}" }
|
||||||
{cx.children()}
|
|
||||||
button { onclick: move |_| count += 1, "Up high!" }
|
button { onclick: move |_| count += 1, "Up high!" }
|
||||||
button { onclick: move |_| count -= 1, "Down low!" }
|
button { onclick: move |_| count -= 1, "Down low!" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ use dioxus_core_macro::*;
|
|||||||
use dioxus_html as dioxus_elements;
|
use dioxus_html as dioxus_elements;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
criterion_group!(mbenches, create_rows);
|
criterion_group!(mbenches, create_rows);
|
||||||
criterion_main!(mbenches);
|
criterion_main!(mbenches);
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,10 @@
|
|||||||
//! if the type supports PartialEq. The Properties trait is used by the rsx! and html! macros to generate the type-safe builder
|
//! if the type supports PartialEq. The Properties trait is used by the rsx! and html! macros to generate the type-safe builder
|
||||||
//! that ensures compile-time required and optional fields on cx.
|
//! that ensures compile-time required and optional fields on cx.
|
||||||
|
|
||||||
use crate::innerlude::{Context, Element, VNode};
|
use crate::{
|
||||||
|
innerlude::{Context, Element, VAnchor, VFragment, VNode},
|
||||||
|
LazyNodes, ScopeChildren,
|
||||||
|
};
|
||||||
/// A component is a wrapper around a Context and some Props that share a lifetime
|
/// A component is a wrapper around a Context and some Props that share a lifetime
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@@ -41,23 +44,39 @@ use crate::innerlude::{Context, Element, VNode};
|
|||||||
pub type Scope<'a, T> = (Context<'a>, &'a T);
|
pub type Scope<'a, T> = (Context<'a>, &'a T);
|
||||||
|
|
||||||
pub struct FragmentProps<'a> {
|
pub struct FragmentProps<'a> {
|
||||||
childen: &'a VNode<'a>,
|
children: ScopeChildren<'a>,
|
||||||
}
|
}
|
||||||
pub struct FragmentPropsBuilder<'a> {
|
|
||||||
childen: Option<&'a VNode<'a>>,
|
pub struct FragmentBuilder<'a, const BUILT: bool> {
|
||||||
|
children: Option<ScopeChildren<'a>>,
|
||||||
|
}
|
||||||
|
impl<'a> FragmentBuilder<'a, false> {
|
||||||
|
pub fn children(mut self, children: ScopeChildren<'a>) -> FragmentBuilder<'a, true> {
|
||||||
|
FragmentBuilder {
|
||||||
|
children: Some(children),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, const A: bool> FragmentBuilder<'a, A> {
|
||||||
|
pub fn build(self) -> FragmentProps<'a> {
|
||||||
|
FragmentProps {
|
||||||
|
children: self.children.unwrap_or_default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Properties for FragmentProps<'a> {
|
impl<'a> Properties for FragmentProps<'a> {
|
||||||
type Builder = FragmentPropsBuilder<'a>;
|
type Builder = FragmentBuilder<'a, false>;
|
||||||
|
|
||||||
const IS_STATIC: bool = false;
|
const IS_STATIC: bool = false;
|
||||||
|
|
||||||
fn builder() -> Self::Builder {
|
fn builder() -> Self::Builder {
|
||||||
todo!()
|
FragmentBuilder { children: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn memoize(&self, other: &Self) -> bool {
|
unsafe fn memoize(&self, other: &Self) -> bool {
|
||||||
todo!()
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,8 +102,10 @@ impl<'a> Properties for FragmentProps<'a> {
|
|||||||
/// You want to use this free-function when your fragment needs a key and simply returning multiple nodes from rsx! won't cut it.
|
/// You want to use this free-function when your fragment needs a key and simply returning multiple nodes from rsx! won't cut it.
|
||||||
///
|
///
|
||||||
#[allow(non_upper_case_globals, non_snake_case)]
|
#[allow(non_upper_case_globals, non_snake_case)]
|
||||||
pub fn Fragment<'a>((_, props): Scope<'a, FragmentProps<'a>>) -> Element<'a> {
|
pub fn Fragment<'a>((cx, props): Scope<'a, FragmentProps<'a>>) -> Element<'a> {
|
||||||
Some(props.childen.decouple())
|
cx.render(Some(LazyNodes::new(|f| {
|
||||||
|
f.fragment_from_iter(&props.children)
|
||||||
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Every "Props" used for a component must implement the `Properties` trait. This trait gives some hints to Dioxus
|
/// Every "Props" used for a component must implement the `Properties` trait. This trait gives some hints to Dioxus
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
//! The logic for this was borrowed from https://docs.rs/stack_dst/0.6.1/stack_dst/. Unfortunately, this crate does not
|
//! The logic for this was borrowed from https://docs.rs/stack_dst/0.6.1/stack_dst/. Unfortunately, this crate does not
|
||||||
//! support non-static closures, so we've implemented the core logic of `ValueA` in this module.
|
//! support non-static closures, so we've implemented the core logic of `ValueA` in this module.
|
||||||
|
|
||||||
use crate::innerlude::{NodeFactory, VNode};
|
use crate::prelude::{NodeFactory, VNode};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
/// A concrete type provider for closures that build VNode structures.
|
/// A concrete type provider for closures that build VNode structures.
|
||||||
@@ -27,7 +27,7 @@ pub struct LazyNodes<'a, 'b> {
|
|||||||
inner: StackNodeStorage<'a, 'b>,
|
inner: StackNodeStorage<'a, 'b>,
|
||||||
}
|
}
|
||||||
|
|
||||||
type StackHeapSize = [usize; 12];
|
type StackHeapSize = [usize; 0];
|
||||||
|
|
||||||
enum StackNodeStorage<'a, 'b> {
|
enum StackNodeStorage<'a, 'b> {
|
||||||
Stack(LazyStack),
|
Stack(LazyStack),
|
||||||
@@ -77,7 +77,7 @@ impl<'a, 'b> LazyNodes<'a, 'b> {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log::debug!("lazy nodes fits on stack!");
|
log::debug!("lazy nodes fits on stack!");
|
||||||
let mut buf: StackHeapSize = [0; 12];
|
let mut buf: StackHeapSize = StackHeapSize::default();
|
||||||
|
|
||||||
assert!(info.len() + round_to_words(size) <= buf.as_ref().len());
|
assert!(info.len() + round_to_words(size) <= buf.as_ref().len());
|
||||||
|
|
||||||
@@ -97,6 +97,8 @@ impl<'a, 'b> LazyNodes<'a, 'b> {
|
|||||||
*dataptr.add(i) = *src_ptr.add(i);
|
*dataptr.add(i) = *src_ptr.add(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::mem::forget(val);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
inner: StackNodeStorage::Stack(LazyStack { _align: [], buf }),
|
inner: StackNodeStorage::Stack(LazyStack { _align: [], buf }),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,9 +65,9 @@ pub(crate) mod innerlude {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub use crate::innerlude::{
|
pub use crate::innerlude::{
|
||||||
Context, DioxusElement, DomEdit, Element, ElementId, EventPriority, MountType, Mutations,
|
Context, DioxusElement, DomEdit, Element, ElementId, EventPriority, LazyNodes, MountType,
|
||||||
NodeFactory, Properties, SchedulerMsg, ScopeChildren, ScopeId, SuspendedContext, TaskHandle,
|
Mutations, NodeFactory, Properties, SchedulerMsg, ScopeChildren, ScopeId, SuspendedContext,
|
||||||
TestDom, ThreadsafeVirtualDom, UserEvent, VNode, VirtualDom, FC,
|
TaskHandle, TestDom, ThreadsafeVirtualDom, UserEvent, VNode, VirtualDom, FC,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
|
|||||||
@@ -765,6 +765,9 @@ impl<'a> ScopeChildren<'a> {
|
|||||||
pub fn new(root: VNode<'a>) -> Self {
|
pub fn new(root: VNode<'a>) -> Self {
|
||||||
Self { root: Some(root) }
|
Self { root: Some(root) }
|
||||||
}
|
}
|
||||||
|
pub fn new_option(root: Option<VNode<'a>>) -> Self {
|
||||||
|
Self { root }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoIterator for &ScopeChildren<'_> {
|
impl IntoIterator for &ScopeChildren<'_> {
|
||||||
@@ -773,7 +776,7 @@ impl IntoIterator for &ScopeChildren<'_> {
|
|||||||
type IntoIter = std::iter::Once<Self>;
|
type IntoIter = std::iter::Once<Self>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
todo!()
|
std::iter::once(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -303,27 +303,8 @@ fn anchors() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn suspended() {
|
fn suspended() {
|
||||||
static App: FC<()> = |(cx, props)| {
|
static App: FC<()> = |(cx, props)| {
|
||||||
let val = use_suspense(
|
let val = use_suspense(cx, || async {}, |cx, p| todo!());
|
||||||
cx,
|
|
||||||
|| async {
|
|
||||||
//
|
|
||||||
},
|
|
||||||
|cx, p| todo!(),
|
|
||||||
// |cx, p| rsx! { "hi "},
|
|
||||||
);
|
|
||||||
|
|
||||||
// let prom = use_task(fetch());
|
|
||||||
|
|
||||||
// Value {
|
|
||||||
// a: value.await,
|
|
||||||
// b: value.await,
|
|
||||||
// f: a.await
|
|
||||||
// div {
|
|
||||||
// div {
|
|
||||||
// hidden: should_hide.await,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
cx.render(rsx! { {val} })
|
cx.render(rsx! { {val} })
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,3 @@ tokio_runtime = ["tokio"]
|
|||||||
dioxus-html = { path = "../html" }
|
dioxus-html = { path = "../html" }
|
||||||
dioxus-hooks = { path = "../hooks" }
|
dioxus-hooks = { path = "../hooks" }
|
||||||
simple_logger = "1.13.0"
|
simple_logger = "1.13.0"
|
||||||
|
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
use dioxus::prelude::Scope;
|
use dioxus::prelude::Scope;
|
||||||
|
use dioxus::ScopeChildren;
|
||||||
use dioxus_core as dioxus;
|
use dioxus_core as dioxus;
|
||||||
use dioxus_core::{Context, Element, LazyNodes, NodeFactory, Properties};
|
use dioxus_core::{Context, Element, LazyNodes, NodeFactory, Properties};
|
||||||
use dioxus_core_macro::Props;
|
use dioxus_core_macro::Props;
|
||||||
@@ -42,6 +43,8 @@ pub struct WebviewWindowProps<'a> {
|
|||||||
|
|
||||||
/// focuse me
|
/// focuse me
|
||||||
onfocused: &'a dyn FnMut(()),
|
onfocused: &'a dyn FnMut(()),
|
||||||
|
|
||||||
|
children: ScopeChildren<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A handle to a
|
/// A handle to a
|
||||||
@@ -70,9 +73,10 @@ pub fn WebviewWindow<'a>((cx, props): Scope<'a, WebviewWindowProps>) -> Element<
|
|||||||
);
|
);
|
||||||
|
|
||||||
// render the children directly
|
// render the children directly
|
||||||
cx.render(LazyNodes::new(move |f: NodeFactory| {
|
todo!()
|
||||||
f.fragment_from_iter(cx.children())
|
// cx.render(LazyNodes::new(move |f: NodeFactory| {
|
||||||
}))
|
// f.fragment_from_iter(cx.children())
|
||||||
|
// }))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WindowHandle {}
|
pub struct WindowHandle {}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
}
|
}
|
||||||
</style> -->
|
</style> -->
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css">
|
||||||
|
<script src="https://cdn.plot.ly/plotly-1.52.3.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ use serde::{Deserialize, Serialize};
|
|||||||
pub use wry;
|
pub use wry;
|
||||||
|
|
||||||
use wry::application::accelerator::{Accelerator, SysMods};
|
use wry::application::accelerator::{Accelerator, SysMods};
|
||||||
use wry::application::event::{Event, StartCause, WindowEvent};
|
use wry::application::event::{ElementState, Event, StartCause, WindowEvent};
|
||||||
use wry::application::event_loop::{self, ControlFlow, EventLoop};
|
use wry::application::event_loop::{self, ControlFlow, EventLoop};
|
||||||
use wry::application::keyboard::KeyCode;
|
use wry::application::keyboard::{Key, KeyCode, ModifiersState};
|
||||||
use wry::application::menu::{MenuBar, MenuItem, MenuItemAttributes};
|
use wry::application::menu::{MenuBar, MenuItem, MenuItemAttributes};
|
||||||
use wry::application::window::Fullscreen;
|
use wry::application::window::Fullscreen;
|
||||||
use wry::webview::{WebView, WebViewBuilder};
|
use wry::webview::{WebView, WebViewBuilder};
|
||||||
@@ -94,6 +94,11 @@ pub fn run<T: 'static + Send + Sync>(
|
|||||||
|
|
||||||
let props_shared = Cell::new(Some(props));
|
let props_shared = Cell::new(Some(props));
|
||||||
|
|
||||||
|
// create local modifier state
|
||||||
|
let mut modifiers = ModifiersState::default();
|
||||||
|
|
||||||
|
let quit_hotkey = Accelerator::new(SysMods::Cmd, KeyCode::KeyQ);
|
||||||
|
|
||||||
event_loop.run(move |event, event_loop, control_flow| {
|
event_loop.run(move |event, event_loop, control_flow| {
|
||||||
*control_flow = ControlFlow::Wait;
|
*control_flow = ControlFlow::Wait;
|
||||||
|
|
||||||
@@ -112,10 +117,8 @@ pub fn run<T: 'static + Send + Sync>(
|
|||||||
first_menu.add_native_item(MenuItem::HideOthers);
|
first_menu.add_native_item(MenuItem::HideOthers);
|
||||||
first_menu.add_native_item(MenuItem::ShowAll);
|
first_menu.add_native_item(MenuItem::ShowAll);
|
||||||
|
|
||||||
let quit_item = first_menu.add_item(
|
first_menu.add_native_item(MenuItem::Quit);
|
||||||
MenuItemAttributes::new("Quit")
|
first_menu.add_native_item(MenuItem::CloseWindow);
|
||||||
.with_accelerators(&Accelerator::new(SysMods::Cmd, KeyCode::KeyQ)),
|
|
||||||
);
|
|
||||||
|
|
||||||
// create second menu
|
// create second menu
|
||||||
let mut second_menu = MenuBar::new();
|
let mut second_menu = MenuBar::new();
|
||||||
@@ -129,6 +132,7 @@ pub fn run<T: 'static + Send + Sync>(
|
|||||||
menu_bar_menu.add_submenu("Second menu", true, second_menu);
|
menu_bar_menu.add_submenu("Second menu", true, second_menu);
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
|
.with_maximized(true)
|
||||||
.with_menu(menu_bar_menu)
|
.with_menu(menu_bar_menu)
|
||||||
.with_title("Dioxus App")
|
.with_title("Dioxus App")
|
||||||
.build(event_loop)
|
.build(event_loop)
|
||||||
@@ -197,6 +201,37 @@ pub fn run<T: 'static + Send + Sync>(
|
|||||||
event, window_id, ..
|
event, window_id, ..
|
||||||
} => match event {
|
} => match event {
|
||||||
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
||||||
|
WindowEvent::Destroyed { .. } => {
|
||||||
|
webviews.remove(&window_id);
|
||||||
|
if webviews.is_empty() {
|
||||||
|
*control_flow = ControlFlow::Exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// catch only pressed event
|
||||||
|
WindowEvent::KeyboardInput { event, .. } => {
|
||||||
|
log::debug!("keybowrd input");
|
||||||
|
if quit_hotkey.matches(&modifiers, &event.physical_key) {
|
||||||
|
log::debug!("quitting");
|
||||||
|
|
||||||
|
webviews.remove(&window_id);
|
||||||
|
if webviews.is_empty() {
|
||||||
|
*control_flow = ControlFlow::Exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// println!(
|
||||||
|
// "KeyEvent: `Shift` + `1` | logical_key: {:?}",
|
||||||
|
// &event.logical_key
|
||||||
|
// );
|
||||||
|
// we can match manually without `Accelerator`
|
||||||
|
|
||||||
|
// else if event.key_without_modifiers() == Key::Character("1")
|
||||||
|
// && modifiers.is_empty()
|
||||||
|
// {
|
||||||
|
// println!("KeyEvent: `1`");
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
WindowEvent::Resized(_) | WindowEvent::Moved(_) => {
|
WindowEvent::Resized(_) | WindowEvent::Moved(_) => {
|
||||||
if let Some(view) = webviews.get_mut(&window_id) {
|
if let Some(view) = webviews.get_mut(&window_id) {
|
||||||
let _ = view.resize();
|
let _ = view.resize();
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
fn main() {}
|
|
||||||
|
|
||||||
// struct CompState {
|
|
||||||
// tasks: Vec<()>,
|
|
||||||
// }
|
|
||||||
// enum Actions {
|
|
||||||
// Add,
|
|
||||||
// MoveUp,
|
|
||||||
// MoveDown,
|
|
||||||
// Remvoe,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// static Component: FC<()> = |(cx, props)|{
|
|
||||||
// let (tasks, dispatch) = use_reducer(
|
|
||||||
// cx,
|
|
||||||
// || CompState { tasks: Vec::new() },
|
|
||||||
// |state, action: Actions| match action {
|
|
||||||
// Actions::Add => state,
|
|
||||||
// Actions::MoveUp => state,
|
|
||||||
// Actions::MoveDown => state,
|
|
||||||
// Actions::Remvoe => state,
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
|
|
||||||
// let tasklist = { (0..10).map(|f| html! { <li></li> }) }.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
// html! {
|
|
||||||
// <div>
|
|
||||||
// <div>
|
|
||||||
// <h1>"Tasks: "</h1>
|
|
||||||
// <ul>
|
|
||||||
// {tasklist}
|
|
||||||
// </ul>
|
|
||||||
// </div>
|
|
||||||
// <div>
|
|
||||||
// <button onclick=|_| dispatch(Action::Add)>{"Add"}</button>
|
|
||||||
// <button onclick=|_| dispatch(Action::MoveUp)>{"MoveUp"}</button>
|
|
||||||
// <button onclick=|_| dispatch(Action::MoveDown)>{"MoveDown"}</button>
|
|
||||||
// <button onclick=|_| dispatch(Action::Remvoe)>{"Remvoe"}</button>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// fn use_reducer<Props, State, Action>(
|
|
||||||
// cx: &mut Context<Props>,
|
|
||||||
// init: fn() -> State,
|
|
||||||
// reducer: fn(State, Action) -> State,
|
|
||||||
// ) -> (State, impl Fn(Action)) {
|
|
||||||
// let ii = init();
|
|
||||||
// (ii, |_| {})
|
|
||||||
// }
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
fn main() {}
|
|
||||||
@@ -126,7 +126,7 @@ impl<'a, T: 'static> UseSharedState<'a, T> {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// TODO: We prevent unncessary notifications only in the hook, but we should figure out some more global lock
|
/// TODO: We prevent unncessary notifications only in the hook, but we should figure out some more global lock
|
||||||
pub fn write(&mut self) -> RefMut<'_, T> {
|
pub fn write(&self) -> RefMut<'_, T> {
|
||||||
self.cx.needs_update();
|
self.cx.needs_update();
|
||||||
self.notify_consumers();
|
self.notify_consumers();
|
||||||
self.value.borrow_mut()
|
self.value.borrow_mut()
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ impl<'a, T: 'static> UseState<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set(&mut self, new_val: T) {
|
pub fn set(&self, new_val: T) {
|
||||||
*self.inner.wip.borrow_mut() = Some(new_val);
|
*self.inner.wip.borrow_mut() = Some(new_val);
|
||||||
self.needs_update();
|
self.needs_update();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
fn main() {}
|
|
||||||
|
|
||||||
enum Routes {
|
|
||||||
Home,
|
|
||||||
Blog,
|
|
||||||
}
|
|
||||||
|
|
||||||
static App: FC<()> = |(cx, props)| {
|
|
||||||
let route = use_router::<Routes>(cx);
|
|
||||||
|
|
||||||
let content = match route {
|
|
||||||
Routes::Home => rsx!(Home {}),
|
|
||||||
Routes::Blog => rsx!(Blog {}),
|
|
||||||
};
|
|
||||||
|
|
||||||
cx.render(rsx! {
|
|
||||||
{content}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
fn use_router<P>(cx: Context) -> &P {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
static Home: FC<()> = |(cx, props)| todo!();
|
|
||||||
static Blog: FC<()> = |(cx, props)| todo!();
|
|
||||||
+4
-10
@@ -31,10 +31,7 @@ impl SsrRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_lazy<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>>(
|
pub fn render_lazy<'a>(&'a mut self, f: Option<LazyNodes<'a, '_>>) -> String {
|
||||||
&'a mut self,
|
|
||||||
f: LazyNodes<'a, F>,
|
|
||||||
) -> String {
|
|
||||||
let bump = &mut self.inner as *mut _;
|
let bump = &mut self.inner as *mut _;
|
||||||
let s = self.render_inner(f);
|
let s = self.render_inner(f);
|
||||||
// reuse the bump's memory
|
// reuse the bump's memory
|
||||||
@@ -42,10 +39,7 @@ impl SsrRenderer {
|
|||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_inner<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>>(
|
fn render_inner<'a>(&'a self, f: Option<LazyNodes<'a, '_>>) -> String {
|
||||||
&'a self,
|
|
||||||
f: LazyNodes<'a, F>,
|
|
||||||
) -> String {
|
|
||||||
let factory = NodeFactory::new(&self.inner);
|
let factory = NodeFactory::new(&self.inner);
|
||||||
let root = f.into_vnode(factory);
|
let root = f.into_vnode(factory);
|
||||||
format!(
|
format!(
|
||||||
@@ -59,7 +53,7 @@ impl SsrRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_lazy<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>>(f: LazyNodes<'a, F>) -> String {
|
pub fn render_lazy<'a>(f: Option<LazyNodes<'a, '_>>) -> String {
|
||||||
let bump = bumpalo::Bump::new();
|
let bump = bumpalo::Bump::new();
|
||||||
let borrowed = ≎
|
let borrowed = ≎
|
||||||
|
|
||||||
@@ -398,7 +392,7 @@ mod tests {
|
|||||||
fn styles() {
|
fn styles() {
|
||||||
static STLYE_APP: FC<()> = |(cx, _)| {
|
static STLYE_APP: FC<()> = |(cx, _)| {
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
div { style: { color: "blue", font_size: "46px" } }
|
div { color: "blue", font_size: "46px" }
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Vendored
-3
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"rust-analyzer.inlayHints.enable": false
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "dioxus-webview-client"
|
|
||||||
version = "0.0.0"
|
|
||||||
edition = "2018"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# the client part of the vdom
|
|
||||||
|
|
||||||
|
|
||||||
this crate is designed to be the "receiving end" of the dioxus virtualdom, using wasm_bindgen to expose an API for the receiving end.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
fn main() {
|
|
||||||
println!("Hello, world!");
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user