wip: start moving events to rc<event>
This commit is contained in:
1 parent
9222d8ece3
commit
b9ff95fa12
21 files changed
+249
-605
No files matched your search
+30
-33
@@ -23,41 +23,38 @@ router = []
|
|||||||
web = []
|
web = []
|
||||||
desktop = []
|
desktop = []
|
||||||
|
|
||||||
[workspace]
|
|
||||||
# members = ["packages/core-macro"]
|
|
||||||
members = [
|
|
||||||
"packages/core-macro",
|
|
||||||
"packages/core",
|
|
||||||
"packages/web",
|
|
||||||
"packages/ssr",
|
|
||||||
"packages/docsite",
|
|
||||||
"packages/atoms",
|
|
||||||
"packages/router",
|
|
||||||
]
|
|
||||||
# "packages/webview",
|
|
||||||
|
|
||||||
# "packages/cli",
|
|
||||||
# "packages/webview",
|
|
||||||
# "packages/hooks",
|
|
||||||
# "packages/ios",
|
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
split-debuginfo = "unpacked"
|
split-debuginfo = "unpacked"
|
||||||
|
|
||||||
# "packages/liveview",
|
|
||||||
# "packages/3d",
|
|
||||||
|
|
||||||
# Built-in
|
[dev-dependencies]
|
||||||
# "packages/webview/client",
|
# For the tide ssr examples
|
||||||
# "packages/router",
|
async-std = { version="1.9.0", features=["attributes"] }
|
||||||
# "packages/webview",
|
tide = { version="0.16.0" }
|
||||||
# "packages/livehost",
|
|
||||||
# "packages/vscode-ext",
|
# For the livewview example
|
||||||
# "packages/recoil",
|
tide-websockets = "0.4.0"
|
||||||
# "packages/redux",
|
serde_millis = "0.1"
|
||||||
# "packages/macro",
|
serde_json = "1"
|
||||||
# TODO @Jon, share the validation code
|
serde = { version="1", features=['derive'] }
|
||||||
# "packages/web",
|
|
||||||
# "packages/cli",
|
# For the doc generator
|
||||||
# "examples",
|
pulldown-cmark = { version="0.8.0", default-features=false }
|
||||||
# "packages/html-macro",
|
|
||||||
|
dioxus-webview = { path="./packages/webview", version="0.0.0" }
|
||||||
|
dioxus-hooks = { path="./packages/hooks", version="0.0.0" }
|
||||||
|
rand = "0.8.4"
|
||||||
|
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
members = [
|
||||||
|
"packages/core-macro",
|
||||||
|
"packages/core",
|
||||||
|
"packages/web",
|
||||||
|
# "packages/ssr",
|
||||||
|
# "packages/docsite",
|
||||||
|
# "packages/atoms",
|
||||||
|
# "packages/router",
|
||||||
|
# "packages/inputs",
|
||||||
|
]
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "dioxus-examples"
|
|
||||||
version = "0.0.0"
|
|
||||||
authors = ["Jonathan Kelley <jkelleyrtp@gmail.com>"]
|
|
||||||
edition = "2018"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
fern = { version = "0.6.0", features = ["colored"] }
|
|
||||||
log = "0.4.1"
|
|
||||||
dioxus = { path = "../packages/dioxus" }
|
|
||||||
dioxus-ssr = { path = "../packages/ssr" }
|
|
||||||
rand = "0.8.2"
|
|
||||||
anyhow = "*"
|
|
||||||
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
# For the tide ssr examples
|
|
||||||
async-std = { version = "1.9.0", features = ["attributes"] }
|
|
||||||
tide = { version = "0.15.0" }
|
|
||||||
|
|
||||||
# For the livewview example
|
|
||||||
tide-websockets = "0.1.0"
|
|
||||||
serde_millis = "0.1"
|
|
||||||
serde_json = "1"
|
|
||||||
serde = { version = "1", features = ['derive'] }
|
|
||||||
|
|
||||||
# For the doc generator
|
|
||||||
pulldown-cmark = { version = "0.8.0", default-features = false }
|
|
||||||
|
|
||||||
dioxus-webview = { path = "../packages/webview", version = "0.0.0" }
|
|
||||||
dioxus-hooks = { path = "../packages/hooks", version = "0.0.0" }
|
|
||||||
|
|
||||||
|
|
||||||
# Shared functionality is done as a lib
|
|
||||||
[lib]
|
|
||||||
path = "common.rs"
|
|
||||||
|
|
||||||
# ================================
|
|
||||||
# Examples are manually keyed in
|
|
||||||
# ================================
|
|
||||||
|
|
||||||
[[example]]
|
|
||||||
path = "example_app.rs"
|
|
||||||
name = "example_app"
|
|
||||||
|
|
||||||
[[example]]
|
|
||||||
path = "website.rs"
|
|
||||||
name = "website"
|
|
||||||
|
|
||||||
# [[example]]
|
|
||||||
# path = "hello_web.rs"
|
|
||||||
# name = "hello_web"
|
|
||||||
|
|
||||||
# [[example]]
|
|
||||||
# path = "tide_ssr.rs"
|
|
||||||
# name = "tide_ssr"
|
|
||||||
|
|
||||||
# [[example]]
|
|
||||||
# path = "doc_generator.rs"
|
|
||||||
# name = "doc_generator"
|
|
||||||
|
|
||||||
# [[example]]
|
|
||||||
# path = "router.rs"
|
|
||||||
# name = "router"
|
|
||||||
|
|
||||||
# [[example]]
|
|
||||||
# path = "fc_macro.rs"
|
|
||||||
# name = "fc_macro"
|
|
||||||
|
|
||||||
# [[example]]
|
|
||||||
# path = "webview.rs"
|
|
||||||
# name = "webview"
|
|
||||||
|
|
||||||
# [[example]]
|
|
||||||
# path = "blah.rs"
|
|
||||||
# name = "blah"
|
|
||||||
|
|
||||||
# [[example]]
|
|
||||||
# path = "live.rs"
|
|
||||||
# name = "live"
|
|
||||||
+3
-1
@@ -1,3 +1,5 @@
|
|||||||
# Examples
|
# Examples
|
||||||
|
|
||||||
Most of these examples are run through webview so you don't need the dioxus cli installed to preview the functionality. Anything labeled `_web` will need to be compiled with Dioxus CLI.
|
Most of these examples are run through webview so you don't need the dioxus cli installed to preview the functionality. Anything labeled `_web` will need to be built with the Dioxus CLI to preview features that only a native bundle can handle.
|
||||||
|
|
||||||
|
List of examples:
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let g = html! {
|
|
||||||
<div>
|
|
||||||
<style> </style>
|
|
||||||
</div>
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
//! Common utilities for integration examples
|
|
||||||
|
|
||||||
pub mod logger {
|
|
||||||
|
|
||||||
use fern::colors::{Color, ColoredLevelConfig};
|
|
||||||
use log::debug;
|
|
||||||
|
|
||||||
pub fn set_up_logging(bin_name: &'static str) {
|
|
||||||
// configure colors for the whole line
|
|
||||||
let colors_line = ColoredLevelConfig::new()
|
|
||||||
.error(Color::Red)
|
|
||||||
.warn(Color::Yellow)
|
|
||||||
// we actually don't need to specify the color for debug and info, they are white by default
|
|
||||||
.info(Color::White)
|
|
||||||
.debug(Color::White)
|
|
||||||
// depending on the terminals color scheme, this is the same as the background color
|
|
||||||
.trace(Color::BrightBlack);
|
|
||||||
|
|
||||||
// configure colors for the name of the level.
|
|
||||||
// since almost all of them are the same as the color for the whole line, we
|
|
||||||
// just clone `colors_line` and overwrite our changes
|
|
||||||
let colors_level = colors_line.clone().info(Color::Green);
|
|
||||||
// here we set up our fern Dispatch
|
|
||||||
fern::Dispatch::new()
|
|
||||||
.format(move |out, message, record| {
|
|
||||||
out.finish(format_args!(
|
|
||||||
"{color_line}[{level}{color_line}] {message}\x1B[0m",
|
|
||||||
color_line = format_args!(
|
|
||||||
"\x1B[{}m",
|
|
||||||
colors_line.get_color(&record.level()).to_fg_str()
|
|
||||||
),
|
|
||||||
level = colors_level.color(record.level()),
|
|
||||||
message = message,
|
|
||||||
));
|
|
||||||
})
|
|
||||||
// set the default log level. to filter out verbose log messages from dependencies, set
|
|
||||||
// this to Warn and overwrite the log level for your crate.
|
|
||||||
.level(log::LevelFilter::Warn)
|
|
||||||
// change log levels for individual modules. Note: This looks for the record's target
|
|
||||||
// field which defaults to the module path but can be overwritten with the `target`
|
|
||||||
// parameter:
|
|
||||||
// `info!(target="special_target", "This log message is about special_target");`
|
|
||||||
.level_for(bin_name, log::LevelFilter::Info)
|
|
||||||
// .level_for("pretty_colored", log::LevelFilter::Trace)
|
|
||||||
// output to stdout
|
|
||||||
.chain(std::io::stdout())
|
|
||||||
.apply()
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
//! The docs generator takes in the `docs` folder and creates a neat, statically-renderer webpage.
|
|
||||||
//! These docs are used to generate the public-facing doc content, showcasing Dioxus' abiltity to
|
|
||||||
//! be used in custom static rendering pipelines.
|
|
||||||
//!
|
|
||||||
//! We use pulldown_cmark as the markdown parser, but instead of outputting html directly, we output
|
|
||||||
//! VNodes to be used in conjuction with our custom templates.
|
|
||||||
|
|
||||||
use dioxus::core::prelude::*;
|
|
||||||
use pulldown_cmark::{Options, Parser};
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let gen_dir = "../docs/";
|
|
||||||
|
|
||||||
let site: FC<()> = |_| {
|
|
||||||
html! {
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static Homepage: FC<()> = |_| {
|
|
||||||
html! {<div> </div>}
|
|
||||||
};
|
|
||||||
|
|
||||||
static DocPage: FC<()> = |_| {
|
|
||||||
html! {<div> </div>}
|
|
||||||
};
|
|
||||||
|
|
||||||
// struct StaticSiteCfg {
|
|
||||||
// gen_dir: &'static str,
|
|
||||||
// homepage_template: fn() -> VNode,
|
|
||||||
// page_template: fn(page: &'static str) -> VNode,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl StaticSiteCfg {
|
|
||||||
// fn render(self) -> anyhow::Result<VNode> {
|
|
||||||
// let StaticSiteCfg { .. } = self;
|
|
||||||
|
|
||||||
// // Set up options and parser. Strikethroughs are not part of the CommonMark standard
|
|
||||||
// // and we therefore must enable it explicitly.
|
|
||||||
// let mut options = Options::empty();
|
|
||||||
// options.insert(Options::ENABLE_STRIKETHROUGH);
|
|
||||||
// let parser = Parser::new_ext(markdown_input, options);
|
|
||||||
|
|
||||||
// //
|
|
||||||
|
|
||||||
// Ok(html! {<div> </div>})
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
//! Example: External Updates
|
//! Example: External Updates
|
||||||
//! -------------------------
|
//! -------------------------
|
||||||
|
//!
|
||||||
//! Cause updates to the VirtualDOM state from outside the component lifecycle.
|
//! Cause updates to the VirtualDOM state from outside the component lifecycle.
|
||||||
//! The root props could be changed or the use_receiver hook could be used.
|
//! The root props could be changed or the use_receiver hook could be used.
|
||||||
//!
|
//!
|
||||||
@@ -30,8 +31,8 @@ fn App(ctx: Context, props: &RootProps) -> VNode {
|
|||||||
|
|
||||||
ctx.render(rsx! {
|
ctx.render(rsx! {
|
||||||
div {
|
div {
|
||||||
a { href="/dogs/"}
|
a { href: "/dogs/"}
|
||||||
a { href="/cats/"}
|
a { href: "/cats/"}
|
||||||
{content}
|
{content}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
use dioxus::prelude::*;
|
|
||||||
use dioxus_ssr::TextRenderer;
|
|
||||||
|
|
||||||
// todo @Jon, support components in the html! macro
|
|
||||||
// let renderer = TextRenderer::new(|_| html! {<Example name="world"/>});
|
|
||||||
fn main() {
|
|
||||||
let renderer = TextRenderer::<()>::new(|_| html! {<div> "Hello world" </div>});
|
|
||||||
let output = renderer.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An example component that demonstrates how to use the functional_component macro
|
|
||||||
/// This macro makes writing functional components elegant, similar to how Rocket parses URIs.
|
|
||||||
///
|
|
||||||
/// You don't actually *need* this macro to be productive, but it makes life easier, and components cleaner.
|
|
||||||
/// This approach also integrates well with tools like Rust-Analyzer.
|
|
||||||
///
|
|
||||||
/// Notice that Context is normally generic over props, but RA doesn't care when in proc-macro mode.
|
|
||||||
/// Also notice that ctx.props still works like you would expect, so migrating to the macro is easy.
|
|
||||||
#[fc]
|
|
||||||
fn example(ctx: &Context, name: String) -> VNode {
|
|
||||||
html! { <div> "Hello, {name}!" </div> }
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
TODO
|
|
||||||
|
|
||||||
/// The macro can also be applied to statics in order to make components less verbose
|
|
||||||
/// The FC type automatically adds the inference, and property fields are automatically added as function arguments
|
|
||||||
#[fc]
|
|
||||||
static Example: FC = |ctx, name: String| {
|
|
||||||
html! { <div> "Hello, {name}!" </div> }
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
// This trait is not exposed to users directly, though they could manually implement this for struct-style components
|
|
||||||
trait Comp {
|
|
||||||
type Props: Properties;
|
|
||||||
fn render(&self, ctx: &mut Context<Self::Props>) -> VNode;
|
|
||||||
fn builder(&self) -> Self::Props;
|
|
||||||
}
|
|
||||||
trait Properties {
|
|
||||||
fn new() -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Properties> Comp for FC<T> {
|
|
||||||
type Props = T;
|
|
||||||
|
|
||||||
fn render(&self, ctx: &mut Context<T>) -> VNode {
|
|
||||||
let g = self(ctx);
|
|
||||||
g
|
|
||||||
}
|
|
||||||
|
|
||||||
fn builder(&self) -> T {
|
|
||||||
T::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused, non_upper_case_globals)]
|
|
||||||
static MyComp: FC<()> = |ctx| {
|
|
||||||
html! {
|
|
||||||
<div>
|
|
||||||
<p> "hello world" </p>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fn my_comp(ctx: &Context<()>) -> VNode {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test() {
|
|
||||||
let mut ctx = Context { props: &() };
|
|
||||||
let f = MyComp.render(&mut ctx);
|
|
||||||
let props = MyComp.builder();
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
//! Example: Hello-web
|
|
||||||
//! -----------------
|
|
||||||
//!
|
|
||||||
//! This example showcases Dioxus-websys to build interactive single-page-applications, much like React.
|
|
||||||
|
|
||||||
fn main() {}
|
|
||||||
+2
-2
@@ -34,8 +34,8 @@ fn App(ctx: Context<()>) -> VNode {
|
|||||||
|
|
||||||
ctx.render(rsx! {
|
ctx.render(rsx! {
|
||||||
div {
|
div {
|
||||||
a { href="/dogs/"}
|
a { href: "/dogs/"}
|
||||||
a { href="/cats/"}
|
a { href: "/cats/"}
|
||||||
{router.render()}
|
{router.render()}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,104 +0,0 @@
|
|||||||
//! Example: Tide Server-Side-Rendering
|
|
||||||
//! -----------------------------------
|
|
||||||
//!
|
|
||||||
//! This demo shows how to use the to_string utility on VNodes to convert them into valid HTML.
|
|
||||||
//! You can use the html! macro to craft webpages generated by the server on-the-fly.
|
|
||||||
//!
|
|
||||||
//! Server-side-renderered webpages are a great use of Rust's async story, where servers can handle
|
|
||||||
//! thousands of simultaneous clients on minimal hardware.
|
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
use dioxus_ssr::TextRenderer;
|
|
||||||
use rand::Rng;
|
|
||||||
use tide::{Request, Response};
|
|
||||||
|
|
||||||
#[async_std::main]
|
|
||||||
async fn main() -> Result<(), std::io::Error> {
|
|
||||||
dioxus_examples::logger::set_up_logging("tide_ssr");
|
|
||||||
|
|
||||||
// Build the API
|
|
||||||
let mut app = tide::new();
|
|
||||||
app.at("/fib/:n").get(fibsum);
|
|
||||||
|
|
||||||
// Launch the server
|
|
||||||
let addr = "127.0.0.1:8080";
|
|
||||||
log::info!("App is ready at {}", addr);
|
|
||||||
log::info!("Navigate to a fibonacci number: http://{}/fib/21", addr);
|
|
||||||
app.listen(addr).await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fib(n: usize) -> usize {
|
|
||||||
if n == 0 || n == 1 {
|
|
||||||
n
|
|
||||||
} else {
|
|
||||||
fib(n - 1) + fib(n - 2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate the fibonacci number for a given request input
|
|
||||||
async fn fibsum(req: Request<()>) -> tide::Result<tide::Response> {
|
|
||||||
let n: usize = req.param("n")?.parse().unwrap_or(0);
|
|
||||||
|
|
||||||
// Start a stopwatch
|
|
||||||
// Compute the nth number in the fibonacci sequence
|
|
||||||
// Stop the stopwatch
|
|
||||||
let start = std::time::Instant::now();
|
|
||||||
let fib_n = fib(n);
|
|
||||||
let duration = start.elapsed().as_nanos();
|
|
||||||
|
|
||||||
// Generate another random number to try
|
|
||||||
let other_fib_to_try = rand::thread_rng().gen_range(1..42);
|
|
||||||
|
|
||||||
let text = TextRenderer::<()>::to_text(html! {
|
|
||||||
<html>
|
|
||||||
|
|
||||||
// Header
|
|
||||||
<head>
|
|
||||||
<meta content="text/html;charset=utf-8" />
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
// Body
|
|
||||||
<body>
|
|
||||||
<div class="flex items-center justify-center flex-col">
|
|
||||||
<div class="flex items-center justify-center">
|
|
||||||
<div class="flex flex-col bg-white rounded p-4 w-full max-w-xs">
|
|
||||||
// Title
|
|
||||||
<div class="font-bold text-xl">
|
|
||||||
{format!("Fibonacci Calculator: n = {}",n)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
// Subtext / description
|
|
||||||
<div class="text-sm text-gray-500">
|
|
||||||
{format!("Calculated in {} nanoseconds",duration)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex flex-row items-center justify-center mt-6">
|
|
||||||
// Main number
|
|
||||||
<div class="font-medium text-6xl">
|
|
||||||
{format!("{}",fib_n)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
// Try another
|
|
||||||
<div class="flex flex-row justify-between mt-6">
|
|
||||||
<a href=format!("http://localhost:8080/fib/{}", other_fib_to_try) class="underline">
|
|
||||||
{"Click to try another number"}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(Response::builder(203)
|
|
||||||
.body(text)
|
|
||||||
.content_type(tide::http::mime::HTML)
|
|
||||||
.build())
|
|
||||||
}
|
|
||||||
@@ -45,81 +45,3 @@ impl Render for Button {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[fc]
|
|
||||||
// fn Button(ctx: Context, onhover: Option<&dyn Fn()>) -> VNode {}
|
|
||||||
|
|
||||||
// h1 {
|
|
||||||
// tag: "type", abc: 123, class: "big small wide short",
|
|
||||||
// "title1"
|
|
||||||
// "title1"
|
|
||||||
// "title1"
|
|
||||||
// "title"
|
|
||||||
// }
|
|
||||||
|
|
||||||
// h1 ("title") {
|
|
||||||
// tag: "type",
|
|
||||||
// abc: 123,
|
|
||||||
// class: "big small wide short",
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // <button
|
|
||||||
// // class="inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow"
|
|
||||||
// // onclick={move |_| set_name("jill")}
|
|
||||||
// // onclick={move |_| set_name("jill")}
|
|
||||||
// // >
|
|
||||||
// // "Jill!"
|
|
||||||
// // </button>
|
|
||||||
|
|
||||||
// button { "Jill!",
|
|
||||||
// class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow"
|
|
||||||
// onclick: move |_| set_name("jill"),
|
|
||||||
// onclick: move |_| set_name("jill"),
|
|
||||||
// }
|
|
||||||
|
|
||||||
// button {
|
|
||||||
// class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow"
|
|
||||||
// onclick: move |_| set_name("jill"),
|
|
||||||
// onclick: move |_| set_name("jill"),
|
|
||||||
// // this is valid
|
|
||||||
// "Jill!",
|
|
||||||
// // this is also valid
|
|
||||||
// {"Jill!"}
|
|
||||||
// }
|
|
||||||
|
|
||||||
// h1 { "Text", class: "inline-block py-4 px-8 mr-6 leading-none" }
|
|
||||||
|
|
||||||
// // <h1 class="inline-block py-4 px-8 mr-6 leading-none">
|
|
||||||
// // "Text"
|
|
||||||
// // </h1>
|
|
||||||
|
|
||||||
// h1 {
|
|
||||||
// div {
|
|
||||||
// h1 {}
|
|
||||||
// h2 {}
|
|
||||||
// Brick {}
|
|
||||||
|
|
||||||
// p {}
|
|
||||||
// p {
|
|
||||||
// tag: "type",
|
|
||||||
// abc: 123,
|
|
||||||
// enabled: true,
|
|
||||||
// class: "big small wide short",
|
|
||||||
|
|
||||||
// a { "abcder" },
|
|
||||||
// h2 { "whatsup", class: "abc-123" },
|
|
||||||
// CustomComponent { a: 123, b: 456, key: "1" },
|
|
||||||
// }
|
|
||||||
|
|
||||||
// div { class: "big small wide short",
|
|
||||||
// div {},
|
|
||||||
// div {},
|
|
||||||
// div {},
|
|
||||||
// div {},
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// h2 {}
|
|
||||||
// h3 {}
|
|
||||||
// "abcd123"
|
|
||||||
+46
-97
@@ -1,9 +1,8 @@
|
|||||||
//! Virtual Events
|
//! This module provides a set of common events for all Dioxus apps to target, regardless of host platform.
|
||||||
//! This module provides a wrapping of platform-specific events with a list of events easier to work with.
|
//! -------------------------------------------------------------------------------------------------------
|
||||||
//! 3rd party renderers are responsible for forming this virtual events from events.
|
|
||||||
//! The goal here is to provide a consistent event interface across all renderer types.
|
|
||||||
//!
|
//!
|
||||||
//! also... websys integerates poorly with rust analyzer, so we handle that for you automatically.
|
//! 3rd party renderers are responsible for converting their native events into these virtual event types. Events might
|
||||||
|
//! be heavy or need to interact through FFI, so the events themselves are designed to be lazy.
|
||||||
|
|
||||||
use crate::innerlude::ScopeIdx;
|
use crate::innerlude::ScopeIdx;
|
||||||
|
|
||||||
@@ -46,15 +45,13 @@ pub enum VirtualEvent {
|
|||||||
MouseEvent(on::MouseEvent),
|
MouseEvent(on::MouseEvent),
|
||||||
PointerEvent(on::PointerEvent),
|
PointerEvent(on::PointerEvent),
|
||||||
|
|
||||||
// todo
|
|
||||||
|
|
||||||
// ImageEvent(event_data::ImageEvent),
|
// ImageEvent(event_data::ImageEvent),
|
||||||
OtherEvent,
|
OtherEvent,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod on {
|
pub mod on {
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
use std::ops::Deref;
|
use std::{ops::Deref, rc::Rc};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
builder::ElementBuilder,
|
builder::ElementBuilder,
|
||||||
@@ -64,15 +61,10 @@ pub mod on {
|
|||||||
|
|
||||||
use super::VirtualEvent;
|
use super::VirtualEvent;
|
||||||
|
|
||||||
macro_rules! event_builder {
|
macro_rules! event_directory {
|
||||||
(
|
( $( $eventdata:ident: [ $( $name:ident )* ]; )* ) => {
|
||||||
$eventdata:ident;
|
|
||||||
$(
|
$(
|
||||||
$(#[$attr:meta])*
|
|
||||||
$name:ident
|
|
||||||
)* ) => {
|
|
||||||
$(
|
$(
|
||||||
$(#[$attr])*
|
|
||||||
pub fn $name<'a>(
|
pub fn $name<'a>(
|
||||||
c: &'_ NodeCtx<'a>,
|
c: &'_ NodeCtx<'a>,
|
||||||
callback: impl Fn($eventdata) + 'a,
|
callback: impl Fn($eventdata) + 'a,
|
||||||
@@ -84,41 +76,61 @@ pub mod on {
|
|||||||
scope: c.scope_ref.arena_idx,
|
scope: c.scope_ref.arena_idx,
|
||||||
callback: bump.alloc(move |evt: VirtualEvent| match evt {
|
callback: bump.alloc(move |evt: VirtualEvent| match evt {
|
||||||
VirtualEvent::$eventdata(event) => callback(event),
|
VirtualEvent::$eventdata(event) => callback(event),
|
||||||
_ => {
|
_ => unreachable!("Downcasted VirtualEvent to wrong event type - this is an internal bug!")
|
||||||
unreachable!("Downcasted VirtualEvent to wrong event type - this is a bug!")
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
};
|
)*
|
||||||
}
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
event_directory! {
|
||||||
|
ClipboardEvent: [copy cut paste];
|
||||||
|
CompositionEvent: [compositionend compositionstart compositionupdate];
|
||||||
|
KeyboardEvent: [keydown keypress keyup];
|
||||||
|
FocusEvent: [focus blur];
|
||||||
|
FormEvent: [change input invalid reset submit];
|
||||||
|
GenericEvent: [];
|
||||||
|
MouseEvent: [
|
||||||
|
click contextmenu doubleclick drag dragend dragenter dragexit
|
||||||
|
dragleave dragover dragstart drop mousedown mouseenter mouseleave
|
||||||
|
mousemove mouseout mouseover mouseup
|
||||||
|
];
|
||||||
|
PointerEvent: [
|
||||||
|
pointerdown pointermove pointerup pointercancel gotpointercapture
|
||||||
|
lostpointercapture pointerenter pointerleave pointerover pointerout
|
||||||
|
];
|
||||||
|
SelectionEvent: [select];
|
||||||
|
TouchEvent: [touchcancel touchend touchmove touchstart];
|
||||||
|
UIEvent: [scroll];
|
||||||
|
WheelEvent: [wheel];
|
||||||
|
MediaEvent: [
|
||||||
|
abort canplay canplaythrough durationchange emptied encrypted
|
||||||
|
ended error loadeddata loadedmetadata loadstart pause play
|
||||||
|
playing progress ratechange seeked seeking stalled suspend
|
||||||
|
timeupdate volumechange waiting
|
||||||
|
];
|
||||||
|
AnimationEvent: [animationstart animationend animationiteration];
|
||||||
|
TransitionEvent: [transitionend];
|
||||||
|
ToggleEvent: [toggle];
|
||||||
|
}
|
||||||
|
|
||||||
pub struct GetModifierKey(pub Box<dyn Fn(usize) -> bool>);
|
pub struct GetModifierKey(pub Box<dyn Fn(usize) -> bool>);
|
||||||
impl std::fmt::Debug for GetModifierKey {
|
impl std::fmt::Debug for GetModifierKey {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
// just skip for now
|
Ok(()) // just skip for now
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DOMDataTransfer clipboardData
|
// DOMDataTransfer clipboardData
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ClipboardEvent {}
|
pub struct ClipboardEvent {}
|
||||||
event_builder! {
|
|
||||||
ClipboardEvent;
|
|
||||||
copy cut paste
|
|
||||||
}
|
|
||||||
|
|
||||||
// string data
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CompositionEvent {
|
pub struct CompositionEvent {
|
||||||
data: String,
|
data: String,
|
||||||
}
|
}
|
||||||
event_builder! {
|
|
||||||
CompositionEvent;
|
|
||||||
compositionend compositionstart compositionupdate
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct KeyboardEvent {
|
pub struct KeyboardEvent {
|
||||||
@@ -134,12 +146,11 @@ pub mod on {
|
|||||||
which: usize,
|
which: usize,
|
||||||
get_modifier_state: GetModifierKey,
|
get_modifier_state: GetModifierKey,
|
||||||
}
|
}
|
||||||
pub struct KeyboardEvent2(pub Box<dyn KeyboardEventT>);
|
pub struct KeyboardEvent2(pub Rc<dyn KeyboardEventT>);
|
||||||
impl std::ops::Deref for KeyboardEvent2 {
|
impl std::ops::Deref for KeyboardEvent2 {
|
||||||
type Target = Box<dyn KeyboardEventT>;
|
type Target = dyn KeyboardEventT;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.0
|
self.0.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,32 +168,16 @@ pub mod on {
|
|||||||
fn get_modifier_state(&self) -> GetModifierKey;
|
fn get_modifier_state(&self) -> GetModifierKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
event_builder! {
|
|
||||||
KeyboardEvent;
|
|
||||||
keydown keypress keyup
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FocusEvent {/* DOMEventTarget relatedTarget */}
|
pub struct FocusEvent {/* DOMEventTarget relatedTarget */}
|
||||||
event_builder! {
|
|
||||||
FocusEvent;
|
|
||||||
focus blur
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FormEvent {
|
pub struct FormEvent {
|
||||||
pub value: String,
|
pub value: String,
|
||||||
}
|
}
|
||||||
event_builder! {
|
|
||||||
FormEvent;
|
|
||||||
change input invalid reset submit
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GenericEvent {/* Error Load */}
|
pub struct GenericEvent {/* Error Load */}
|
||||||
event_builder! {
|
|
||||||
GenericEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MouseEvent(pub Box<RawMouseEvent>);
|
pub struct MouseEvent(pub Box<RawMouseEvent>);
|
||||||
@@ -210,12 +205,6 @@ pub mod on {
|
|||||||
self.0.as_ref()
|
self.0.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event_builder! {
|
|
||||||
MouseEvent;
|
|
||||||
click contextmenu doubleclick drag dragend dragenter dragexit
|
|
||||||
dragleave dragover dragstart drop mousedown mouseenter mouseleave
|
|
||||||
mousemove mouseout mouseover mouseup
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PointerEvent(Box<RawPointerEvent>);
|
pub struct PointerEvent(Box<RawPointerEvent>);
|
||||||
@@ -255,18 +244,9 @@ pub mod on {
|
|||||||
pointer_type: String,
|
pointer_type: String,
|
||||||
is_primary: bool,
|
is_primary: bool,
|
||||||
}
|
}
|
||||||
event_builder! {
|
|
||||||
PointerEvent;
|
|
||||||
pointerdown pointermove pointerup pointercancel gotpointercapture
|
|
||||||
lostpointercapture pointerenter pointerleave pointerover pointerout
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SelectionEvent {}
|
pub struct SelectionEvent {}
|
||||||
event_builder! {
|
|
||||||
SelectionEvent;
|
|
||||||
select
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TouchEvent {
|
pub struct TouchEvent {
|
||||||
@@ -282,20 +262,12 @@ pub mod on {
|
|||||||
// touches: DOMTouchList,
|
// touches: DOMTouchList,
|
||||||
// getModifierState(key): boolean
|
// getModifierState(key): boolean
|
||||||
}
|
}
|
||||||
event_builder! {
|
|
||||||
TouchEvent;
|
|
||||||
touchcancel touchend touchmove touchstart
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UIEvent {
|
pub struct UIEvent {
|
||||||
// DOMAbstractView view
|
// DOMAbstractView view
|
||||||
detail: i32,
|
detail: i32,
|
||||||
}
|
}
|
||||||
event_builder! {
|
|
||||||
UIEvent;
|
|
||||||
scroll
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct WheelEvent {
|
pub struct WheelEvent {
|
||||||
@@ -304,20 +276,9 @@ pub mod on {
|
|||||||
delta_y: i32,
|
delta_y: i32,
|
||||||
delta_z: i32,
|
delta_z: i32,
|
||||||
}
|
}
|
||||||
event_builder! {
|
|
||||||
WheelEvent;
|
|
||||||
wheel
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MediaEvent {}
|
pub struct MediaEvent {}
|
||||||
event_builder! {
|
|
||||||
MediaEvent;
|
|
||||||
abort canplay canplaythrough durationchange emptied encrypted
|
|
||||||
ended error loadeddata loadedmetadata loadstart pause play
|
|
||||||
playing progress ratechange seeked seeking stalled suspend
|
|
||||||
timeupdate volumechange waiting
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo!
|
// todo!
|
||||||
// imageevent clashes with media event
|
// imageevent clashes with media event
|
||||||
@@ -336,10 +297,6 @@ pub mod on {
|
|||||||
pseudo_element: String,
|
pseudo_element: String,
|
||||||
elapsed_time: f32,
|
elapsed_time: f32,
|
||||||
}
|
}
|
||||||
event_builder! {
|
|
||||||
AnimationEvent;
|
|
||||||
animationstart animationend animationiteration
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TransitionEvent {
|
pub struct TransitionEvent {
|
||||||
@@ -347,15 +304,7 @@ pub mod on {
|
|||||||
pseudo_element: String,
|
pseudo_element: String,
|
||||||
elapsed_time: f32,
|
elapsed_time: f32,
|
||||||
}
|
}
|
||||||
event_builder! {
|
|
||||||
TransitionEvent;
|
|
||||||
transitionend
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ToggleEvent {}
|
pub struct ToggleEvent {}
|
||||||
event_builder! {
|
|
||||||
ToggleEvent;
|
|
||||||
toggle
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -274,7 +274,7 @@ impl VirtualDom {
|
|||||||
// Now, there are events in the queue
|
// Now, there are events in the queue
|
||||||
let mut updates = self.event_queue.0.as_ref().borrow_mut();
|
let mut updates = self.event_queue.0.as_ref().borrow_mut();
|
||||||
|
|
||||||
// Order the nodes by their height, we want the biggest nodes on the top
|
// Order the nodes by their height, we want the nodes with the smallest depth on top
|
||||||
// This prevents us from running the same component multiple times
|
// This prevents us from running the same component multiple times
|
||||||
updates.sort_unstable();
|
updates.sort_unstable();
|
||||||
|
|
||||||
@@ -300,6 +300,7 @@ impl VirtualDom {
|
|||||||
// let cur_component = inner.get_mut(update.idx).unwrap();
|
// let cur_component = inner.get_mut(update.idx).unwrap();
|
||||||
|
|
||||||
cur_component.run_scope()?;
|
cur_component.run_scope()?;
|
||||||
|
// diff_machine.change_list.load_known_root(1);
|
||||||
|
|
||||||
diff_machine.diff_node(cur_component.old_frame(), cur_component.next_frame());
|
diff_machine.diff_node(cur_component.old_frame(), cur_component.next_frame());
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "dioxus-inputs"
|
||||||
|
version = "0.0.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Cross-platform controlled inputs
|
||||||
|
|
||||||
|
Dioxus does not include controlled inputs in Dioxus-Core. This would require core integration with HTML that is inherently not cross platform. Instead, this crate exists to provide a bunch of cross-platform input types that abstract over renderer quirks.
|
||||||
|
|
||||||
|
Included is:
|
||||||
|
|
||||||
|
- Button
|
||||||
|
- Checkbox
|
||||||
|
- Color
|
||||||
|
- Date
|
||||||
|
- Datetime-local
|
||||||
|
- Email
|
||||||
|
- File
|
||||||
|
- Hidden
|
||||||
|
- Image
|
||||||
|
- Month
|
||||||
|
- Number
|
||||||
|
- Password
|
||||||
|
- Radio
|
||||||
|
- Range
|
||||||
|
- Reset
|
||||||
|
- Search
|
||||||
|
- Submit
|
||||||
|
- Tel
|
||||||
|
- Text
|
||||||
|
- Time
|
||||||
|
- Url
|
||||||
|
- Week
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
assert_eq!(2 + 2, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,9 +36,12 @@ version = "0.3.50"
|
|||||||
features = [
|
features = [
|
||||||
"Comment",
|
"Comment",
|
||||||
"Document",
|
"Document",
|
||||||
|
# "DataTransfer",
|
||||||
"Element",
|
"Element",
|
||||||
"HtmlElement",
|
"HtmlElement",
|
||||||
"HtmlInputElement",
|
"HtmlInputElement",
|
||||||
|
"HtmlSelectElement",
|
||||||
|
"HtmlTextAreaElement",
|
||||||
"EventTarget",
|
"EventTarget",
|
||||||
"HtmlCollection",
|
"HtmlCollection",
|
||||||
"Node",
|
"Node",
|
||||||
@@ -60,6 +63,7 @@ features = [
|
|||||||
"DocumentType",
|
"DocumentType",
|
||||||
"CharacterData",
|
"CharacterData",
|
||||||
"HtmlOptionElement",
|
"HtmlOptionElement",
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
use dioxus_core as dioxus;
|
||||||
|
use dioxus_core::prelude::*;
|
||||||
|
use dioxus_web::WebsysRenderer;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// wasm_logger::init(wasm_logger::Config::new(log::Level::Debug));
|
||||||
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
|
log::info!("hello world");
|
||||||
|
wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App));
|
||||||
|
}
|
||||||
|
|
||||||
|
static App: FC<()> = |ctx| {
|
||||||
|
let (val, set_val) = use_state(&ctx, || "asd".to_string());
|
||||||
|
|
||||||
|
ctx.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"
|
||||||
|
h1 { class: "text-gray-200 text-center font-extrabold -mt-3 text-3xl",
|
||||||
|
"Text Input Example"
|
||||||
|
}
|
||||||
|
div { class: "mb-4"
|
||||||
|
input {
|
||||||
|
placeholder: "Username"
|
||||||
|
class: "shadow appearance-none rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
|
id: "username"
|
||||||
|
type: "text"
|
||||||
|
value: "{val}"
|
||||||
|
oninput: move |evet| {
|
||||||
|
log::debug!("Value is {:#?}", evet);
|
||||||
|
set_val(evet.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p { "Val is: {val}" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
static Example: FC<()> = |ctx| {
|
||||||
|
ctx.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"
|
||||||
|
h1 { class: "text-gray-200 text-center font-extrabold -mt-3 text-3xl",
|
||||||
|
"Text Input Example"
|
||||||
|
}
|
||||||
|
UserInput {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
static UserInput: FC<()> = |ctx| {
|
||||||
|
let (val, set_val) = use_state(&ctx, || "asd".to_string());
|
||||||
|
|
||||||
|
rsx!{ in ctx,
|
||||||
|
div { class: "mb-4"
|
||||||
|
input { class: "shadow appearance-none rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
|
placeholder: "Username"
|
||||||
|
id: "username"
|
||||||
|
type: "text"
|
||||||
|
oninput: move |evet| {
|
||||||
|
log::debug!("Value is {:#?}", evet);
|
||||||
|
set_val(evet.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p { "Val is: {val}" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
@@ -7,7 +7,9 @@ use dioxus_core::{
|
|||||||
};
|
};
|
||||||
use fxhash::FxHashMap;
|
use fxhash::FxHashMap;
|
||||||
use wasm_bindgen::{closure::Closure, JsCast};
|
use wasm_bindgen::{closure::Closure, JsCast};
|
||||||
use web_sys::{window, Document, Element, Event, HtmlInputElement, HtmlOptionElement, Node};
|
use web_sys::{
|
||||||
|
window, Document, Element, Event, HtmlElement, HtmlInputElement, HtmlOptionElement, Node,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
||||||
pub struct CacheId(u32);
|
pub struct CacheId(u32);
|
||||||
@@ -564,11 +566,38 @@ fn virtual_event_from_websys_event(event: &web_sys::Event) -> VirtualEvent {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
"change" | "input" | "invalid" | "reset" | "submit" => {
|
"change" => {
|
||||||
|
let evt: web_sys::Event = event.clone().dyn_into().expect("wrong error typ");
|
||||||
|
todo!()
|
||||||
|
// VirtualEvent::FormEvent(FormEvent {value:})
|
||||||
|
}
|
||||||
|
|
||||||
|
"input" | "invalid" | "reset" | "submit" => {
|
||||||
// is a special react events
|
// is a special react events
|
||||||
let evt: web_sys::InputEvent = event.clone().dyn_into().expect("wrong event type");
|
let evt: web_sys::InputEvent = event.clone().dyn_into().expect("wrong event type");
|
||||||
let value: Option<String> = (&evt).data();
|
let this: web_sys::EventTarget = evt.target().unwrap();
|
||||||
let value = value.unwrap_or_default();
|
|
||||||
|
let value = (&this)
|
||||||
|
.dyn_ref()
|
||||||
|
.map(|input: &web_sys::HtmlInputElement| input.value())
|
||||||
|
.or_else(|| {
|
||||||
|
(&this)
|
||||||
|
.dyn_ref()
|
||||||
|
.map(|input: &web_sys::HtmlTextAreaElement| input.value())
|
||||||
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
(&this)
|
||||||
|
.dyn_ref::<web_sys::HtmlElement>()
|
||||||
|
.unwrap()
|
||||||
|
.text_content()
|
||||||
|
})
|
||||||
|
.expect("only an InputElement or TextAreaElement or an element with contenteditable=true can have an oninput event listener");
|
||||||
|
|
||||||
|
// let p2 = evt.data_transfer();
|
||||||
|
|
||||||
|
// let value: Option<String> = (&evt).data();
|
||||||
|
// let value = val;
|
||||||
|
// let value = value.unwrap_or_default();
|
||||||
// let value = (&evt).data().expect("No data to unwrap");
|
// let value = (&evt).data().expect("No data to unwrap");
|
||||||
|
|
||||||
// todo - this needs to be a "controlled" event
|
// todo - this needs to be a "controlled" event
|
||||||
|
|||||||
+11
-5
@@ -177,6 +177,11 @@
|
|||||||
//! };
|
//! };
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
|
pub mod prelude {
|
||||||
|
//! A glob import that includes helper types like FC, rsx!, html!, and required traits
|
||||||
|
pub use dioxus_core::prelude::*;
|
||||||
|
pub use dioxus_core_macro::fc;
|
||||||
|
}
|
||||||
// Just a heads-up, the core functionality of dioxus rests in Dioxus-Core. This crate just wraps a bunch of utilities
|
// Just a heads-up, the core functionality of dioxus rests in Dioxus-Core. This crate just wraps a bunch of utilities
|
||||||
// together and exports their namespaces to something predicatble.
|
// together and exports their namespaces to something predicatble.
|
||||||
#[cfg(feature = "core")]
|
#[cfg(feature = "core")]
|
||||||
@@ -186,12 +191,12 @@ pub mod core {
|
|||||||
// Re-export core completely
|
// Re-export core completely
|
||||||
pub use dioxus_core::*;
|
pub use dioxus_core::*;
|
||||||
}
|
}
|
||||||
pub mod prelude {
|
|
||||||
//! A glob import that includes helper types like FC, rsx!, html!, and required traits
|
|
||||||
pub use dioxus_core::prelude::*;
|
|
||||||
pub use dioxus_core_macro::fc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Input elements work differently on different platforms.
|
||||||
|
// This module helps abstract over Selects, TextInputs, TextAreas, Radios, etc for a cross-platform input experience
|
||||||
|
pub mod inputs {
|
||||||
|
//! Cross-platform abstractions over user inputs
|
||||||
|
}
|
||||||
#[cfg(feature = "web")]
|
#[cfg(feature = "web")]
|
||||||
pub mod web {
|
pub mod web {
|
||||||
//! A web-sys based renderer for building fast and interactive web applications
|
//! A web-sys based renderer for building fast and interactive web applications
|
||||||
@@ -214,6 +219,7 @@ pub mod testing {
|
|||||||
}
|
}
|
||||||
#[cfg(feature = "atoms")]
|
#[cfg(feature = "atoms")]
|
||||||
pub mod atoms {}
|
pub mod atoms {}
|
||||||
|
|
||||||
#[cfg(feature = "desktop")]
|
#[cfg(feature = "desktop")]
|
||||||
pub mod desktop {
|
pub mod desktop {
|
||||||
//! A webview based renderer for building desktop applications with Dioxus
|
//! A webview based renderer for building desktop applications with Dioxus
|
||||||
|
|||||||
Reference in new issue
Block a user