yew_stdweb/lib.rs
1#![allow(clippy::needless_doctest_main)]
2#![doc(html_logo_url = "https://static.yew.rs/logo.svg")]
3
4//! # Yew Framework - API Documentation
5//!
6//! Yew is a modern Rust framework for creating multi-threaded front-end web apps using WebAssembly
7//!
8//! - Features a macro for declaring interactive HTML with Rust expressions. Developers who have experience using JSX in React should feel quite at home when using Yew.
9//! - Achieves high performance by minimizing DOM API calls for each page render and by making it easy to offload processing to background web workers.
10//! - Supports JavaScript interoperability, allowing developers to leverage NPM packages and integrate with existing JavaScript applications.
11//!
12//! ### Supported Targets
13//! - `wasm32-unknown-unknown`
14#![cfg_attr(
15 feature = "std_web",
16 doc = "\
17 - `wasm32-unknown-emscripten`
18 - `asmjs-unknown-emscripten`"
19)]
20//!
21//! ### Important Notes
22//! - Yew is not (yet) production ready but is great for side projects and internal tools
23# instead."
26)]
27# instead."
32)]
33//!
34//! ## Example
35//!
36//! ```rust
37//! use yew::prelude::*;
38//!
39//! enum Msg {
40//! AddOne,
41//! }
42//!
43//! struct Model {
44//! link: ComponentLink<Self>,
45//! value: i64,
46//! }
47//!
48//! impl Component for Model {
49//! type Message = Msg;
50//! type Properties = ();
51//!
52//! fn create(_props: Self::Properties, link: ComponentLink<Self>) -> Self {
53//! Self {
54//! link,
55//! value: 0,
56//! }
57//! }
58//!
59//! fn update(&mut self, msg: Self::Message) -> ShouldRender {
60//! match msg {
61//! Msg::AddOne => {
62//! self.value += 1;
63//! true
64//! }
65//! }
66//! }
67//!
68//! fn change(&mut self, _props: Self::Properties) -> ShouldRender {
69//! false
70//! }
71//!
72//! fn view(&self) -> Html {
73//! html! {
74//! <div>
75//! <button onclick=self.link.callback(|_| Msg::AddOne)>{ "+1" }</button>
76//! <p>{ self.value }</p>
77//! </div>
78//! }
79//! }
80//! }
81//!
82//!# fn dont_execute() {
83//! fn main() {
84//! yew::start_app::<Model>();
85//! }
86//!# }
87//! ```
88//!
89
90#![deny(
91 missing_docs,
92 missing_debug_implementations,
93 bare_trait_objects,
94 anonymous_parameters,
95 elided_lifetimes_in_paths
96)]
97#![allow(macro_expanded_macro_exports_accessed_by_absolute_paths)]
98#![recursion_limit = "512"]
99extern crate self as yew;
100
101/// This macro provides a convenient way to create [`Classes`].
102///
103/// The macro takes a list of items similar to the [`vec!`] macro and returns a [`Classes`] instance.
104/// Each item can be of any type that implements `Into<Classes>` (See the implementations on [`Classes`] to learn what types can be used).
105///
106/// # Example
107///
108/// ```
109/// # use yew::prelude::*;
110/// # fn test() {
111/// let conditional_class = Some("my-other-class");
112/// let vec_of_classes = vec!["one-bean", "two-beans", "three-beans", "a-very-small-casserole"];
113///
114/// html! {
115/// <div class=classes!("my-container-class", conditional_class, vec_of_classes)>
116/// // ...
117/// </div>
118/// };
119/// # }
120/// ```
121pub use yew_macro::classes;
122
123/// This macro implements JSX-like templates.
124///
125/// This macro always returns [`Html`].
126/// If you need to preserve the type of a component, use the [`html_nested!`] macro instead.
127///
128/// More information about using the `html!` macro can be found in the [Yew Docs]
129///
130/// [`Html`]: ./html/type.Html.html
131/// [`html_nested!`]: ./macro.html_nested.html
132/// [Yew Docs]: https://yew.rs/docs/en/concepts/html/
133pub use yew_macro::html;
134
135/// This macro is similar to [`html!`], but preserves the component type instead
136/// of wrapping it in [`Html`].
137///
138/// That macro is useful when, for example, in a typical implementation of a list
139/// component (let's assume it's called `List`).
140/// In a typical implementation you might find two component types -- `List` and `ListItem`.
141/// Only `ListItem` components are allowed to be children of List`.
142///
143/// You can find an example implementation of this in the [`nested_list`] example.
144/// That example shows, how to create static lists with their children.
145///
146/// ```
147/// # use yew::prelude::*;
148/// use yew::html::ChildrenRenderer;
149/// use yew::virtual_dom::VChild;
150///
151/// #[derive(Clone, Properties)]
152/// struct List {
153/// children: ChildrenRenderer<ListItem>,
154/// }
155/// impl Component for List {
156/// # type Message = ();
157/// type Properties = Self;
158/// // ...
159/// # fn create(props: Self::Properties, _: ComponentLink<Self>) -> Self { props }
160/// # fn update(&mut self, _: Self::Message) -> ShouldRender { false }
161/// # fn change(&mut self, _: Self::Properties) -> ShouldRender { false }
162/// # fn view(&self) -> Html { unimplemented!() }
163/// }
164///
165/// #[derive(Clone)]
166/// struct ListItem;
167/// impl Component for ListItem {
168/// # type Message = ();
169/// # type Properties = ();
170/// // ...
171/// # fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self { Self }
172/// # fn update(&mut self, _: Self::Message) -> ShouldRender { false }
173/// # fn change(&mut self, _: Self::Properties) -> ShouldRender { false }
174/// # fn view(&self) -> Html { unimplemented!() }
175/// }
176///
177/// // Required for ChildrenRenderer
178/// impl From<VChild<ListItem>> for ListItem {
179/// fn from(child: VChild<ListItem>) -> Self { Self }
180/// }
181///
182/// impl Into<Html> for ListItem {
183/// fn into(self) -> Html { self.view() }
184/// }
185///
186/// // You can use `List` with nested `ListItem` components.
187/// // Using any other kind of element would result in a compile error.
188/// # fn test() -> Html {
189/// html! {
190/// <List>
191/// <ListItem/>
192/// <ListItem/>
193/// <ListItem/>
194/// </List>
195/// }
196/// # }
197/// # fn test_iter() -> Html {
198/// # let some_iter = (0..10);
199/// // In many cases you might want to create the content dynamically.
200/// // To do this, you can use the following code:
201/// html! {
202/// <List>
203/// { for some_iter.map(|_| html_nested!{ <ListItem/> }) }
204/// </List>
205/// }
206/// # }
207/// ```
208///
209/// If you used the [`html!`] macro instead of `html_nested!`, the code would
210/// not compile because we explicitly indicated to the compiler that `List`
211/// can only contain elements of type `ListItem` using [`ChildrenRenderer<ListItem>`],
212/// while [`html!`] creates items of type [`Html`].
213///
214///
215/// [`html!`]: ./macro.html.html
216/// [`Html`]: ./html/type.Html.html
217/// [`nested_list`]: https://github.com/yewstack/yew/tree/master/examples/nested_list
218/// [`ChildrenRenderer<ListItem>`]: ./html/struct.ChildrenRenderer.html
219pub use yew_macro::html_nested;
220
221/// Build [`Properties`] outside of the [`html!`] macro.
222///
223/// It's already possible to create properties like normal Rust structs
224/// but if there are lots of optional props the end result is often needlessly verbose.
225/// This macro allows you to build properties the same way the [`html!`] macro does.
226///
227/// The macro doesn't support special props like `ref` and `key`, they need to be set in the [`html!`] macro.
228///
229/// You can read more about `Properties` in the [Yew Docs].
230///
231/// # Example
232///
233/// ```
234/// # use yew::prelude::*;
235/// use std::borrow::Cow;
236///
237/// #[derive(Clone, Properties)]
238/// struct Props {
239/// #[prop_or_default]
240/// id: usize,
241/// name: Cow<'static, str>,
242/// }
243///
244/// struct Model(Props);
245/// impl Component for Model {
246/// # type Message = ();
247/// type Properties = Props;
248/// // ...
249/// # fn create(_props: Self::Properties, _link: ComponentLink<Self>) -> Self { unimplemented!() }
250/// # fn update(&mut self, _msg: Self::Message) -> ShouldRender { unimplemented!() }
251/// # fn change(&mut self, _props: Self::Properties) -> ShouldRender { unimplemented!() }
252/// # fn view(&self) -> Html { unimplemented!() }
253/// }
254///
255/// # fn foo() -> Html {
256/// // You can build props directly ...
257/// let props = yew::props!(Props { name: Cow::from("Minka") });
258/// # assert_eq!(props.name, "Minka");
259/// // ... or build the associated properties of a component
260/// let props = yew::props!(Model::Properties { id: 2, name: Cow::from("Lemmy") });
261/// # assert_eq!(props.id, 2);
262///
263/// // Use the `with props` syntax to create a component with the props.
264/// html! {
265/// <Model key=1 with props />
266/// }
267/// # }
268/// ```
269///
270/// [`html!`]: ./macro.html.html
271/// [`Properties`]: ./html/trait.Properties.html
272/// [yew docs]: https://yew.rs/docs/en/concepts/components/properties
273pub use yew_macro::props;
274
275/// This module contains macros which implements html! macro and JSX-like templates
276pub mod macros {
277 pub use crate::classes;
278 pub use crate::html;
279 pub use crate::html_nested;
280 pub use crate::props;
281}
282
283pub mod app;
284pub mod callback;
285pub mod format;
286pub mod html;
287mod scheduler;
288pub mod utils;
289pub mod virtual_dom;
290
291#[cfg(feature = "agent")]
292pub mod agent;
293#[cfg(feature = "services")]
294pub mod services;
295
296#[cfg(feature = "web_sys")]
297pub use web_sys;
298
299/// The module that contains all events available in the framework.
300pub mod events {
301 use cfg_if::cfg_if;
302
303 pub use crate::html::{ChangeData, InputData};
304
305 cfg_if! {
306 if #[cfg(feature = "std_web")] {
307 #[doc(no_inline)]
308 pub use stdweb::web::event::{
309 BlurEvent, ClickEvent, ContextMenuEvent, DoubleClickEvent, DragDropEvent, DragEndEvent,
310 DragEnterEvent, DragEvent, DragExitEvent, DragLeaveEvent, DragOverEvent, DragStartEvent,
311 FocusEvent, GotPointerCaptureEvent, IKeyboardEvent, IMouseEvent, IPointerEvent,
312 KeyDownEvent, KeyPressEvent, KeyUpEvent, LostPointerCaptureEvent, MouseDownEvent,
313 MouseEnterEvent, MouseLeaveEvent, MouseMoveEvent, MouseOutEvent, MouseOverEvent,
314 MouseUpEvent, MouseWheelEvent, PointerCancelEvent, PointerDownEvent, PointerEnterEvent,
315 PointerLeaveEvent, PointerMoveEvent, PointerOutEvent, PointerOverEvent, PointerUpEvent,
316 ScrollEvent, SubmitEvent, TouchCancel, TouchEnd, TouchEnter, TouchMove, TouchStart,
317 };
318 } else if #[cfg(feature = "web_sys")] {
319 #[doc(no_inline)]
320 pub use web_sys::{
321 AnimationEvent, DragEvent, ErrorEvent, Event, FocusEvent, InputEvent, KeyboardEvent,
322 MouseEvent, PointerEvent, ProgressEvent, TouchEvent, TransitionEvent, UiEvent, WheelEvent,
323 };
324 }
325 }
326}
327
328use cfg_match::cfg_match;
329
330/// Initializes yew framework. It should be called first.
331pub fn initialize() {
332 cfg_match! {
333 feature = "std_web" => stdweb::initialize(),
334 feature = "web_sys" => std::panic::set_hook(Box::new(console_error_panic_hook::hook)),
335 };
336}
337
338/// Starts event loop.
339pub fn run_loop() {
340 #[cfg(feature = "std_web")]
341 stdweb::event_loop();
342}
343
344/// Starts an app mounted to a body of the document.
345pub fn start_app<COMP>()
346where
347 COMP: Component,
348 COMP::Properties: Default,
349{
350 initialize();
351 App::<COMP>::new().mount_to_body();
352 run_loop();
353}
354
355/// Starts an app mounted to a body of the document.
356pub fn start_app_with_props<COMP>(props: COMP::Properties)
357where
358 COMP: Component,
359{
360 initialize();
361 App::<COMP>::new().mount_to_body_with_props(props);
362 run_loop();
363}
364
365/// The Yew Prelude
366///
367/// The purpose of this module is to alleviate imports of many common types:
368///
369/// ```
370/// # #![allow(unused_imports)]
371/// use yew::prelude::*;
372/// ```
373pub mod prelude {
374 #[cfg(feature = "agent")]
375 pub use crate::agent::{Bridge, Bridged, Dispatched, Threaded};
376 pub use crate::app::App;
377 pub use crate::callback::Callback;
378 pub use crate::events::*;
379 pub use crate::html::{
380 Children, ChildrenWithProps, Classes, Component, ComponentLink, Html, NodeRef, Properties,
381 ShouldRender,
382 };
383 pub use crate::macros::{classes, html, html_nested};
384
385 /// Prelude module for creating worker.
386 #[cfg(feature = "agent")]
387 pub mod worker {
388 pub use crate::agent::{
389 Agent, AgentLink, Bridge, Bridged, Context, HandlerId, Job, Private, Public,
390 };
391 }
392}
393
394pub use self::prelude::*;