mirror of
https://github.com/yewstack/yew.git
synced 2025-12-08 21:26:25 +00:00
yew: function_component -> component (#3885)
This commit is contained in:
parent
16fd8b085a
commit
f0b182d391
@ -85,7 +85,7 @@ where
|
||||
/// The Oneshot Agent Provider.
|
||||
///
|
||||
/// This component provides its children access to an oneshot agent.
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn OneshotProvider<T, C = Bincode>(props: &WorkerProviderProps) -> Html
|
||||
where
|
||||
T: Oneshot + 'static,
|
||||
|
||||
@ -85,7 +85,7 @@ where
|
||||
/// The Reactor Agent Provider.
|
||||
///
|
||||
/// This component provides its children access to a reactor agent.
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn ReactorProvider<R, C = Bincode>(props: &WorkerProviderProps) -> Html
|
||||
where
|
||||
R: 'static + Reactor,
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
//! # }
|
||||
//! # }
|
||||
//! use my_worker_mod::MyWorker; // note that <MyWorker as yew_agent::Worker>::Output == WorkerResponseType
|
||||
//! #[function_component(UseWorkerBridge)]
|
||||
//! #[component(UseWorkerBridge)]
|
||||
//! fn bridge() -> Html {
|
||||
//! let counter = use_state(|| 0);
|
||||
//!
|
||||
|
||||
@ -104,7 +104,7 @@ where
|
||||
/// The Worker Agent Provider.
|
||||
///
|
||||
/// This component provides its children access to a worker agent.
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn WorkerProvider<W, C = Bincode>(props: &WorkerProviderProps) -> Html
|
||||
where
|
||||
W: Worker + 'static,
|
||||
|
||||
@ -35,7 +35,7 @@ impl Parse for FunctionComponent {
|
||||
item => {
|
||||
return Err(syn::Error::new_spanned(
|
||||
item,
|
||||
"`function_component` attribute can only be applied to functions",
|
||||
"`component` attribute can only be applied to functions",
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
@ -258,12 +258,12 @@ mod value_into_some_value_in_props {
|
||||
optional: ::std::option::Option<usize>
|
||||
}
|
||||
|
||||
#[::yew::function_component]
|
||||
#[::yew::component]
|
||||
fn Inner(_props: &Props) -> ::yew::html::Html {
|
||||
::yew::html!{}
|
||||
}
|
||||
|
||||
#[::yew::function_component]
|
||||
#[::yew::component]
|
||||
fn Main() -> ::yew::html::Html {
|
||||
::yew::html! {<>
|
||||
<Inner required=3 optional=5/>
|
||||
|
||||
@ -5,7 +5,7 @@ struct Props {
|
||||
a: usize,
|
||||
}
|
||||
|
||||
#[function_component(Comp)]
|
||||
#[component(Comp)]
|
||||
struct Test;
|
||||
|
||||
fn main() {}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
error: `function_component` attribute can only be applied to functions
|
||||
error: `component` attribute can only be applied to functions
|
||||
--> $DIR/applied-to-non-fn-fail.rs:9:1
|
||||
|
|
||||
9 | struct Test;
|
||||
|
||||
@ -5,7 +5,7 @@ struct Props {
|
||||
a: usize,
|
||||
}
|
||||
|
||||
#[function_component(Comp)]
|
||||
#[component(Comp)]
|
||||
async fn comp(props: &Props) -> Html {
|
||||
html! {
|
||||
<p>
|
||||
|
||||
@ -5,7 +5,7 @@ struct Props {
|
||||
a: usize,
|
||||
}
|
||||
|
||||
#[function_component(let)]
|
||||
#[component(let)]
|
||||
fn comp(props: &Props) -> Html {
|
||||
html! {
|
||||
<p>
|
||||
@ -14,7 +14,7 @@ fn comp(props: &Props) -> Html {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(x, y, z)]
|
||||
#[component(x, y, z)]
|
||||
fn comp_2(props: &Props) -> Html {
|
||||
html! {
|
||||
<p>
|
||||
@ -23,7 +23,7 @@ fn comp_2(props: &Props) -> Html {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(124)]
|
||||
#[component(124)]
|
||||
fn comp_3(props: &Props) -> Html {
|
||||
html! {
|
||||
<p>
|
||||
@ -32,7 +32,7 @@ fn comp_3(props: &Props) -> Html {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(component)]
|
||||
#[component(component)]
|
||||
fn component(props: &Props) -> Html {
|
||||
html! {
|
||||
<p>
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
error: expected identifier, found keyword `let`
|
||||
--> tests/function_component_attr/bad-name-fail.rs:8:22
|
||||
--> tests/function_component_attr/bad-name-fail.rs:8:13
|
||||
|
|
||||
8 | #[function_component(let)]
|
||||
| ^^^
|
||||
8 | #[component(let)]
|
||||
| ^^^
|
||||
|
||||
error: unexpected token
|
||||
--> tests/function_component_attr/bad-name-fail.rs:17:23
|
||||
--> tests/function_component_attr/bad-name-fail.rs:17:14
|
||||
|
|
||||
17 | #[function_component(x, y, z)]
|
||||
| ^
|
||||
17 | #[component(x, y, z)]
|
||||
| ^
|
||||
|
||||
error: expected identifier
|
||||
--> tests/function_component_attr/bad-name-fail.rs:26:22
|
||||
--> tests/function_component_attr/bad-name-fail.rs:26:13
|
||||
|
|
||||
26 | #[function_component(124)]
|
||||
| ^^^
|
||||
26 | #[component(124)]
|
||||
| ^^^
|
||||
|
||||
error: the component must not have the same name as the function
|
||||
--> tests/function_component_attr/bad-name-fail.rs:35:22
|
||||
--> tests/function_component_attr/bad-name-fail.rs:35:13
|
||||
|
|
||||
35 | #[function_component(component)]
|
||||
| ^^^^^^^^^
|
||||
35 | #[component(component)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
@ -5,7 +5,7 @@ struct Props {
|
||||
a: usize,
|
||||
}
|
||||
|
||||
#[function_component(Comp)]
|
||||
#[component(Comp)]
|
||||
fn comp(props: Props) -> Html {
|
||||
html! {
|
||||
<p>
|
||||
|
||||
@ -5,10 +5,10 @@ struct Props {
|
||||
a: usize,
|
||||
}
|
||||
|
||||
#[function_component(Comp1)]
|
||||
#[component(Comp1)]
|
||||
fn comp_1(_props: &Props) {}
|
||||
|
||||
#[function_component(Comp)]
|
||||
#[component(Comp)]
|
||||
fn comp(_props: &Props) -> u32 {
|
||||
1
|
||||
}
|
||||
|
||||
@ -7,10 +7,10 @@ error: function components must return `yew::Html` or `yew::HtmlResult`
|
||||
error[E0277]: the trait bound `u32: IntoHtmlResult` is not satisfied
|
||||
--> tests/function_component_attr/bad-return-type-fail.rs:11:1
|
||||
|
|
||||
11 | #[function_component(Comp)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `IntoHtmlResult` is not implemented for `u32`
|
||||
11 | #[component(Comp)]
|
||||
| ^^^^^^^^^^^^^^^^^^ the trait `IntoHtmlResult` is not implemented for `u32`
|
||||
|
|
||||
= help: the following other types implement trait `IntoHtmlResult`:
|
||||
VNode
|
||||
Result<VNode, RenderError>
|
||||
= note: this error originates in the attribute macro `function_component` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
= note: this error originates in the attribute macro `component` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
@ -5,7 +5,7 @@ struct Props {
|
||||
a: usize,
|
||||
}
|
||||
|
||||
#[function_component(Comp)]
|
||||
#[component(Comp)]
|
||||
const fn comp(props: &Props) -> Html {
|
||||
html! {
|
||||
<p>
|
||||
|
||||
@ -5,7 +5,7 @@ struct Props {
|
||||
a: usize,
|
||||
}
|
||||
|
||||
#[function_component(Comp)]
|
||||
#[component(Comp)]
|
||||
extern "C" fn comp(props: &Props) -> Html {
|
||||
html! {
|
||||
<p>
|
||||
|
||||
@ -5,7 +5,7 @@ struct Props {
|
||||
a: usize,
|
||||
}
|
||||
|
||||
#[function_component(Comp)]
|
||||
#[component(Comp)]
|
||||
fn comp<'a>(props: &'a Props) -> Html {
|
||||
html! {
|
||||
<p>
|
||||
|
||||
@ -40,7 +40,7 @@ struct Props {
|
||||
a: ::std::primitive::usize,
|
||||
}
|
||||
|
||||
#[::yew::function_component(Comp)]
|
||||
#[::yew::component(Comp)]
|
||||
fn comp<P>(_props: &P) -> ::yew::Html
|
||||
where
|
||||
P: ::yew::Properties + ::std::cmp::PartialEq,
|
||||
@ -50,14 +50,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[::yew::function_component(Comp1)]
|
||||
#[::yew::component(Comp1)]
|
||||
fn comp1<T1, T2>(_props: &()) -> ::yew::Html {
|
||||
::yew::html! {
|
||||
<p></p>
|
||||
}
|
||||
}
|
||||
|
||||
#[::yew::function_component(ConstGenerics)]
|
||||
#[::yew::component(ConstGenerics)]
|
||||
fn const_generics<const N: ::std::primitive::i32>() -> ::yew::Html {
|
||||
::yew::html! {
|
||||
<div>
|
||||
|
||||
@ -5,7 +5,7 @@ struct Props {
|
||||
a: usize,
|
||||
}
|
||||
|
||||
#[function_component(Comp)]
|
||||
#[component(Comp)]
|
||||
fn comp<P>(_props: &P) -> Html
|
||||
where
|
||||
P: Properties + PartialEq,
|
||||
|
||||
@ -55,8 +55,8 @@ error[E0277]: the trait bound `MissingTypeBounds: yew::Properties` is not satisf
|
||||
note: required by a bound in `Comp`
|
||||
--> tests/function_component_attr/generic-props-fail.rs:11:8
|
||||
|
|
||||
8 | #[function_component(Comp)]
|
||||
| ---- required by a bound in this struct
|
||||
8 | #[component(Comp)]
|
||||
| ---- required by a bound in this struct
|
||||
...
|
||||
11 | P: Properties + PartialEq,
|
||||
| ^^^^^^^^^^ required by this bound in `Comp`
|
||||
@ -65,8 +65,8 @@ note: required by a bound in `Comp`
|
||||
error[E0599]: the function or associated item `new` exists for struct `VChild<Comp<MissingTypeBounds>>`, but its trait bounds were not satisfied
|
||||
--> tests/function_component_attr/generic-props-fail.rs:27:14
|
||||
|
|
||||
8 | #[function_component(Comp)]
|
||||
| ------------------------- doesn't satisfy `Comp<MissingTypeBounds>: yew::BaseComponent`
|
||||
8 | #[component(Comp)]
|
||||
| ---------------- doesn't satisfy `Comp<MissingTypeBounds>: yew::BaseComponent`
|
||||
...
|
||||
27 | html! { <Comp<MissingTypeBounds> /> };
|
||||
| ^^^^ function or associated item cannot be called on `VChild<Comp<MissingTypeBounds>>` due to unsatisfied trait bounds
|
||||
@ -106,10 +106,10 @@ error[E0107]: missing generics for struct `Comp`
|
||||
| ^^^^ expected 1 generic argument
|
||||
|
|
||||
note: struct defined here, with 1 generic parameter: `P`
|
||||
--> tests/function_component_attr/generic-props-fail.rs:8:22
|
||||
--> tests/function_component_attr/generic-props-fail.rs:8:13
|
||||
|
|
||||
8 | #[function_component(Comp)]
|
||||
| ^^^^
|
||||
8 | #[component(Comp)]
|
||||
| ^^^^
|
||||
9 | fn comp<P>(_props: &P) -> Html
|
||||
| -
|
||||
help: add missing generic argument
|
||||
|
||||
@ -3,7 +3,7 @@ use yew::prelude::*;
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
struct Ctx;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
if let Some(_m) = use_context::<Ctx>() {
|
||||
use_context::<Ctx>().unwrap();
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
)]
|
||||
struct Ctx;
|
||||
|
||||
#[::yew::prelude::function_component]
|
||||
#[::yew::prelude::component]
|
||||
fn Comp() -> ::yew::prelude::Html {
|
||||
::yew::prelude::use_context::<Ctx>().unwrap();
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ struct Props {
|
||||
a: usize,
|
||||
}
|
||||
|
||||
#[function_component(Comp)]
|
||||
#[component(Comp)]
|
||||
fn comp(props: &'static Props) -> Html {
|
||||
html! {
|
||||
<p>
|
||||
|
||||
@ -5,7 +5,7 @@ struct Props {
|
||||
a: usize,
|
||||
}
|
||||
|
||||
#[function_component(Comp)]
|
||||
#[component(Comp)]
|
||||
fn comp(props: &Props, invalid: String) -> Html {
|
||||
html! {
|
||||
<p>
|
||||
@ -15,7 +15,7 @@ fn comp(props: &Props, invalid: String) -> Html {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(Comp)]
|
||||
#[component(Comp)]
|
||||
fn comp3(props: &Props, invalid: String, another_invalid: u32) -> Html {
|
||||
html! {
|
||||
<p>
|
||||
|
||||
@ -5,7 +5,7 @@ struct Props {
|
||||
a: usize,
|
||||
}
|
||||
|
||||
#[function_component(Comp)]
|
||||
#[component(Comp)]
|
||||
fn comp(props: &mut Props) -> Html {
|
||||
html! {
|
||||
<p>
|
||||
|
||||
@ -4,7 +4,7 @@ struct Props {
|
||||
a: usize,
|
||||
}
|
||||
|
||||
#[::yew::prelude::function_component]
|
||||
#[::yew::prelude::component]
|
||||
fn Comp(props: &Props) -> ::yew::prelude::Html {
|
||||
::yew::prelude::html! {
|
||||
<p>
|
||||
|
||||
@ -11,12 +11,12 @@ impl<A> ::std::cmp::PartialEq for CompProps<A> {
|
||||
}
|
||||
}
|
||||
|
||||
#[::yew::prelude::function_component(Comp)]
|
||||
#[::yew::prelude::component(Comp)]
|
||||
pub fn comp<A = ()>(_props: &CompProps<A>) -> ::yew::prelude::Html {
|
||||
::std::todo!()
|
||||
}
|
||||
|
||||
#[::yew::prelude::function_component(App)]
|
||||
#[::yew::prelude::component(App)]
|
||||
pub fn app() -> ::yew::prelude::Html {
|
||||
::yew::prelude::html! { <Comp /> } // No generics here.
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ struct Props {
|
||||
a: ::std::primitive::usize,
|
||||
}
|
||||
|
||||
#[::yew::function_component(Comp)]
|
||||
#[::yew::component(Comp)]
|
||||
fn comp(props: &Props) -> ::yew::Html {
|
||||
::yew::html! {
|
||||
<p>
|
||||
|
||||
@ -8,7 +8,7 @@ struct Props {
|
||||
struct Test;
|
||||
|
||||
impl Test {
|
||||
#[function_component(Comp)]
|
||||
#[component(Comp)]
|
||||
fn comp(self, props: &Props) -> Html {
|
||||
html! {
|
||||
<p>
|
||||
|
||||
@ -36,7 +36,7 @@ pub struct u8;
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct usize;
|
||||
|
||||
#[::yew::function_component(Comp)]
|
||||
#[::yew::component(Comp)]
|
||||
fn comp() -> ::yew::Html {
|
||||
::yew::html! {
|
||||
<p>
|
||||
|
||||
@ -14,7 +14,7 @@ macro_rules! use_some_macro {
|
||||
};
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
let content = if true {
|
||||
use_some_macro!()
|
||||
|
||||
@ -15,7 +15,7 @@ macro_rules! use_some_macro {
|
||||
};
|
||||
}
|
||||
|
||||
#[::yew::functional::function_component]
|
||||
#[::yew::functional::component]
|
||||
fn Comp() -> ::yew::Html {
|
||||
let a = use_some_macro!();
|
||||
let b = use_some_macro!("b");
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use yew::prelude::*;
|
||||
use yew_macro::{use_prepared_state_with_closure, use_prepared_state_without_closure};
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> HtmlResult {
|
||||
use_prepared_state_with_closure!(123)?;
|
||||
|
||||
@ -18,7 +18,7 @@ fn Comp() -> HtmlResult {
|
||||
Ok(Html::default())
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp2() -> HtmlResult {
|
||||
use_prepared_state_without_closure!(123)?;
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use yew::prelude::*;
|
||||
use yew_macro::{use_transitive_state_with_closure, use_transitive_state_without_closure};
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> HtmlResult {
|
||||
use_transitive_state_with_closure!(123)?;
|
||||
|
||||
@ -16,7 +16,7 @@ fn Comp() -> HtmlResult {
|
||||
Ok(Html::default())
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp2() -> HtmlResult {
|
||||
use_transitive_state_without_closure!(123)?;
|
||||
|
||||
|
||||
@ -151,7 +151,7 @@ pub struct RenderPropProps {
|
||||
pub children: ::yew::Callback<()>,
|
||||
}
|
||||
|
||||
#[::yew::function_component]
|
||||
#[::yew::component]
|
||||
pub fn RenderPropComp(_props: &RenderPropProps) -> ::yew::Html {
|
||||
::yew::html! {}
|
||||
}
|
||||
|
||||
@ -140,7 +140,7 @@ fn compile_fail() {
|
||||
pub struct HtmlInPropsProperties {
|
||||
pub header: ::yew::Html,
|
||||
}
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn HtmlInProps(props: &HtmlInPropsProperties) -> Html { let _ = (); unimplemented!() }
|
||||
|
||||
fn not_expressions() {
|
||||
|
||||
@ -1,20 +1,20 @@
|
||||
use yew::prelude::*;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn App() -> Html {
|
||||
html! {
|
||||
<Foo />
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn App1() -> Html {
|
||||
html! {
|
||||
<Foo bar={"bar".to_string()} />
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn App2() -> Html {
|
||||
html! {
|
||||
<Foo bar={"bar".to_string()} baz={42} />
|
||||
@ -27,7 +27,7 @@ pub struct FooProps {
|
||||
pub baz: u32,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn Foo(_props: &FooProps) -> Html {
|
||||
html! {}
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ where
|
||||
}
|
||||
|
||||
/// A wrapper around `<a>` tag to be used with [`Router`](crate::Router)
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn Link<R, Q = (), S = ()>(props: &LinkProps<R, Q, S>) -> Html
|
||||
where
|
||||
R: Routable + 'static,
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct RedirectProps<R: Routable> {
|
||||
}
|
||||
|
||||
/// A component that will redirect to specified route when rendered.
|
||||
#[function_component(Redirect)]
|
||||
#[component(Redirect)]
|
||||
pub fn redirect<R>(props: &RedirectProps<R>) -> Html
|
||||
where
|
||||
R: Routable + 'static,
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
//! NotFound,
|
||||
//! }
|
||||
//!
|
||||
//! #[function_component(Secure)]
|
||||
//! #[component(Secure)]
|
||||
//! fn secure() -> Html {
|
||||
//! let navigator = use_navigator().unwrap();
|
||||
//!
|
||||
@ -32,7 +32,7 @@
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! #[function_component(Main)]
|
||||
//! #[component(Main)]
|
||||
//! fn app() -> Html {
|
||||
//! html! {
|
||||
//! <BrowserRouter>
|
||||
|
||||
@ -66,7 +66,7 @@ impl NavigatorContext {
|
||||
///
|
||||
/// The implementation is separated to make sure <Router /> has the same virtual dom layout as
|
||||
/// the <BrowserRouter /> and <HashRouter />.
|
||||
#[function_component(BaseRouter)]
|
||||
#[component(BaseRouter)]
|
||||
fn base_router(props: &RouterProps) -> Html {
|
||||
let RouterProps {
|
||||
history,
|
||||
@ -149,7 +149,7 @@ fn base_router(props: &RouterProps) -> Html {
|
||||
/// If you are building a web application, you may want to consider using [`BrowserRouter`] instead.
|
||||
///
|
||||
/// You only need one `<Router />` for each application.
|
||||
#[function_component(Router)]
|
||||
#[component(Router)]
|
||||
pub fn router(props: &RouterProps) -> Html {
|
||||
html! {
|
||||
<BaseRouter ..{props.clone()} />
|
||||
@ -173,7 +173,7 @@ pub struct ConcreteRouterProps {
|
||||
///
|
||||
/// The router will by default use the value declared in `<base href="..." />` as its basename.
|
||||
/// You may also specify a different basename with props.
|
||||
#[function_component(BrowserRouter)]
|
||||
#[component(BrowserRouter)]
|
||||
pub fn browser_router(props: &ConcreteRouterProps) -> Html {
|
||||
let ConcreteRouterProps { children, basename } = props.clone();
|
||||
let history = use_state(|| AnyHistory::from(BrowserHistory::new()));
|
||||
@ -196,7 +196,7 @@ pub fn browser_router(props: &ConcreteRouterProps) -> Html {
|
||||
/// # Warning
|
||||
///
|
||||
/// Prefer [`BrowserRouter`] whenever possible and use this as a last resort.
|
||||
#[function_component(HashRouter)]
|
||||
#[component(HashRouter)]
|
||||
pub fn hash_router(props: &ConcreteRouterProps) -> Html {
|
||||
let ConcreteRouterProps { children, basename } = props.clone();
|
||||
let history = use_state(|| AnyHistory::from(HashHistory::new()));
|
||||
|
||||
@ -24,7 +24,7 @@ where
|
||||
/// Otherwise `html! {}` is rendered and a message is logged to console
|
||||
/// stating that no route can be matched.
|
||||
/// See the [crate level document][crate] for more information.
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn Switch<R>(props: &SwitchProps<R>) -> Html
|
||||
where
|
||||
R: Routable + 'static,
|
||||
|
||||
@ -5,7 +5,7 @@ use std::time::Duration;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
|
||||
use yew::functional::function_component;
|
||||
use yew::functional::component;
|
||||
use yew::platform::time::sleep;
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
@ -35,7 +35,7 @@ struct NoProps {
|
||||
id: u32,
|
||||
}
|
||||
|
||||
#[function_component(No)]
|
||||
#[component(No)]
|
||||
fn no(props: &NoProps) -> Html {
|
||||
let route = props.id.to_string();
|
||||
|
||||
@ -49,7 +49,7 @@ fn no(props: &NoProps) -> Html {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(Comp)]
|
||||
#[component(Comp)]
|
||||
fn component() -> Html {
|
||||
let navigator = use_navigator().unwrap();
|
||||
|
||||
@ -100,7 +100,7 @@ fn component() -> Html {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(Root)]
|
||||
#[component(Root)]
|
||||
fn root() -> Html {
|
||||
html! {
|
||||
<BrowserRouter basename="/base/">
|
||||
|
||||
@ -5,7 +5,7 @@ use std::time::Duration;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
|
||||
use yew::functional::function_component;
|
||||
use yew::functional::component;
|
||||
use yew::platform::time::sleep;
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
@ -35,7 +35,7 @@ struct NoProps {
|
||||
id: u32,
|
||||
}
|
||||
|
||||
#[function_component(No)]
|
||||
#[component(No)]
|
||||
fn no(props: &NoProps) -> Html {
|
||||
let route = props.id.to_string();
|
||||
|
||||
@ -49,7 +49,7 @@ fn no(props: &NoProps) -> Html {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(Comp)]
|
||||
#[component(Comp)]
|
||||
fn component() -> Html {
|
||||
let navigator = use_navigator().unwrap();
|
||||
|
||||
@ -100,7 +100,7 @@ fn component() -> Html {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(Root)]
|
||||
#[component(Root)]
|
||||
fn root() -> Html {
|
||||
html! {
|
||||
<BrowserRouter>
|
||||
|
||||
@ -5,7 +5,7 @@ use std::time::Duration;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
|
||||
use yew::functional::function_component;
|
||||
use yew::functional::component;
|
||||
use yew::platform::time::sleep;
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
@ -35,7 +35,7 @@ struct NoProps {
|
||||
id: u32,
|
||||
}
|
||||
|
||||
#[function_component(No)]
|
||||
#[component(No)]
|
||||
fn no(props: &NoProps) -> Html {
|
||||
let route = props.id.to_string();
|
||||
|
||||
@ -49,7 +49,7 @@ fn no(props: &NoProps) -> Html {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(Comp)]
|
||||
#[component(Comp)]
|
||||
fn component() -> Html {
|
||||
let navigator = use_navigator().unwrap();
|
||||
|
||||
@ -100,7 +100,7 @@ fn component() -> Html {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(Root)]
|
||||
#[component(Root)]
|
||||
fn root() -> Html {
|
||||
html! {
|
||||
<HashRouter>
|
||||
|
||||
@ -8,7 +8,7 @@ use gloo::utils::window;
|
||||
use js_sys::{JsString, Object, Reflect};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
|
||||
use yew::functional::function_component;
|
||||
use yew::functional::component;
|
||||
use yew::platform::time::sleep;
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
@ -59,7 +59,7 @@ struct NavigationMenuProps {
|
||||
assertion: Option<fn(&Navigator, &Location)>,
|
||||
}
|
||||
|
||||
#[function_component(NavigationMenu)]
|
||||
#[component(NavigationMenu)]
|
||||
fn navigation_menu(props: &NavigationMenuProps) -> Html {
|
||||
let navigator = use_navigator().unwrap();
|
||||
let location = use_location().unwrap();
|
||||
@ -98,7 +98,7 @@ fn navigation_menu(props: &NavigationMenuProps) -> Html {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(RootForBrowserRouter)]
|
||||
#[component(RootForBrowserRouter)]
|
||||
fn root_for_browser_router() -> Html {
|
||||
html! {
|
||||
<BrowserRouter>
|
||||
@ -140,7 +140,7 @@ struct BasenameProps {
|
||||
assertion: fn(&Navigator, &Location),
|
||||
}
|
||||
|
||||
#[function_component(RootForBasename)]
|
||||
#[component(RootForBasename)]
|
||||
fn root_for_basename(props: &BasenameProps) -> Html {
|
||||
html! {
|
||||
<BrowserRouter basename={props.basename.clone()}>
|
||||
@ -283,7 +283,7 @@ async fn link_with_basename(correct_initial_path: bool) {
|
||||
assert_eq!(RENDERS.load(Ordering::Relaxed), 5);
|
||||
}
|
||||
|
||||
#[function_component(RootForHashRouter)]
|
||||
#[component(RootForHashRouter)]
|
||||
fn root_for_hash_router() -> Html {
|
||||
html! {
|
||||
<HashRouter>
|
||||
|
||||
@ -20,7 +20,7 @@ enum AppRoute {
|
||||
Search { query: String },
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
let switch = move |routes: AppRoute| match routes {
|
||||
AppRoute::Root => html! {
|
||||
@ -40,7 +40,7 @@ fn Comp() -> Html {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(Root)]
|
||||
#[component(Root)]
|
||||
fn root() -> Html {
|
||||
html! {
|
||||
<BrowserRouter>
|
||||
|
||||
@ -299,7 +299,7 @@ mod tests {
|
||||
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
|
||||
|
||||
use super::*;
|
||||
use crate::{function_component, html, Html};
|
||||
use crate::{component, html, Html};
|
||||
|
||||
wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
@ -373,7 +373,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
async fn macro_syntax_works() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
html! { <a href="https://example.com/" ~alt={"abc"} ~data-bool={JsValue::from_bool(true)} /> }
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ use crate::functional::{hook, use_memo};
|
||||
/// pub callback: Callback<String, String>,
|
||||
/// }
|
||||
///
|
||||
/// #[function_component(MyComponent)]
|
||||
/// #[component(MyComponent)]
|
||||
/// fn my_component(props: &Props) -> Html {
|
||||
/// let greeting = props.callback.emit("Yew".to_string());
|
||||
///
|
||||
@ -29,7 +29,7 @@ use crate::functional::{hook, use_memo};
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// #[function_component(UseCallback)]
|
||||
/// #[component(UseCallback)]
|
||||
/// fn callback() -> Html {
|
||||
/// let counter = use_state(|| 0);
|
||||
/// let onclick = {
|
||||
|
||||
@ -16,7 +16,7 @@ use crate::functional::{Hook, HookContext};
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use yew::{ContextProvider, function_component, html, use_context, use_state, Html};
|
||||
/// use yew::{ContextProvider, component, html, use_context, use_state, Html};
|
||||
///
|
||||
///
|
||||
/// /// App theme
|
||||
@ -27,7 +27,7 @@ use crate::functional::{Hook, HookContext};
|
||||
/// }
|
||||
///
|
||||
/// /// Main component
|
||||
/// #[function_component]
|
||||
/// #[component]
|
||||
/// pub fn App() -> Html {
|
||||
/// let ctx = use_state(|| Theme {
|
||||
/// foreground: "#000000".to_owned(),
|
||||
@ -47,7 +47,7 @@ use crate::functional::{Hook, HookContext};
|
||||
///
|
||||
/// /// The toolbar.
|
||||
/// /// This component has access to the context
|
||||
/// #[function_component]
|
||||
/// #[component]
|
||||
/// pub fn Toolbar() -> Html {
|
||||
/// html! {
|
||||
/// <div>
|
||||
@ -58,7 +58,7 @@ use crate::functional::{Hook, HookContext};
|
||||
///
|
||||
/// /// Button placed in `Toolbar`.
|
||||
/// /// As this component is a child of `ThemeContextProvider` in the component tree, it also has access to the context.
|
||||
/// #[function_component]
|
||||
/// #[component]
|
||||
/// pub fn ThemedButton() -> Html {
|
||||
/// let theme = use_context::<Theme>().expect("no ctx found");
|
||||
///
|
||||
|
||||
@ -134,7 +134,7 @@ where
|
||||
/// use yew::prelude::*;
|
||||
/// # use std::rc::Rc;
|
||||
///
|
||||
/// #[function_component(UseEffect)]
|
||||
/// #[component(UseEffect)]
|
||||
/// fn effect() -> Html {
|
||||
/// let counter = use_state(|| 0);
|
||||
///
|
||||
@ -186,7 +186,7 @@ where
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use yew::{function_component, html, use_effect_with, Html, Properties};
|
||||
/// use yew::{component, html, use_effect_with, Html, Properties};
|
||||
/// # use gloo::console::log;
|
||||
///
|
||||
/// #[derive(Properties, PartialEq)]
|
||||
@ -194,7 +194,7 @@ where
|
||||
/// pub is_loading: bool,
|
||||
/// }
|
||||
///
|
||||
/// #[function_component]
|
||||
/// #[component]
|
||||
/// fn HelloWorld(props: &Props) -> Html {
|
||||
/// let is_loading = props.is_loading.clone();
|
||||
///
|
||||
@ -216,10 +216,10 @@ where
|
||||
/// render of a component.
|
||||
///
|
||||
/// ```rust
|
||||
/// use yew::{function_component, html, use_effect_with, Html};
|
||||
/// use yew::{component, html, use_effect_with, Html};
|
||||
/// # use gloo::console::log;
|
||||
///
|
||||
/// #[function_component]
|
||||
/// #[component]
|
||||
/// fn HelloWorld() -> Html {
|
||||
/// use_effect_with((), move |_| {
|
||||
/// log!("I got rendered, yay!");
|
||||
@ -235,10 +235,10 @@ where
|
||||
/// It will only get called when the component is removed from view / gets destroyed.
|
||||
///
|
||||
/// ```rust
|
||||
/// use yew::{function_component, html, use_effect_with, Html};
|
||||
/// use yew::{component, html, use_effect_with, Html};
|
||||
/// # use gloo::console::log;
|
||||
///
|
||||
/// #[function_component]
|
||||
/// #[component]
|
||||
/// fn HelloWorld() -> Html {
|
||||
/// use_effect_with((), move |_| {
|
||||
/// || {
|
||||
|
||||
@ -80,7 +80,7 @@ mod feat_nightly {
|
||||
/// ```rust
|
||||
/// use yew::prelude::*;
|
||||
///
|
||||
/// #[function_component]
|
||||
/// #[component]
|
||||
/// fn ManuallyUpdatedDate() -> Html {
|
||||
/// let trigger = use_force_update();
|
||||
/// let onclick = use_state(move || Callback::from(move |_| trigger.force_update()));
|
||||
@ -116,7 +116,7 @@ pub fn use_force_update() -> impl Hook<Output = UseForceUpdateHandle> {
|
||||
mod nightly_test {
|
||||
use yew::prelude::*;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn ManuallyUpdatedDate() -> Html {
|
||||
let trigger = use_force_update();
|
||||
let _ = move || trigger();
|
||||
|
||||
@ -56,7 +56,7 @@ where
|
||||
/// pub step: usize,
|
||||
/// }
|
||||
///
|
||||
/// #[function_component(UseMemo)]
|
||||
/// #[component(UseMemo)]
|
||||
/// fn memo(props: &Props) -> Html {
|
||||
/// // Will only get recalculated if `props.step` value changes
|
||||
/// let message = use_memo(props.step, |step| {
|
||||
|
||||
@ -299,7 +299,7 @@ where
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// #[function_component(UseReducer)]
|
||||
/// #[component(UseReducer)]
|
||||
/// fn reducer() -> Html {
|
||||
/// // The use_reducer hook takes an initialization function which will be called only once.
|
||||
/// let counter = use_reducer(CounterState::default);
|
||||
|
||||
@ -34,7 +34,7 @@ impl<T: 'static, F: FnOnce() -> T> Hook for UseRef<F> {
|
||||
/// use web_sys::HtmlInputElement;
|
||||
/// use yew::prelude::*;
|
||||
///
|
||||
/// #[function_component(UseRef)]
|
||||
/// #[component(UseRef)]
|
||||
/// fn ref_hook() -> Html {
|
||||
/// let message = use_state(|| "".to_string());
|
||||
/// let message_count = use_ref(|| Cell::new(0));
|
||||
@ -88,7 +88,7 @@ where
|
||||
/// use web_sys::HtmlInputElement;
|
||||
/// use yew::prelude::*;
|
||||
///
|
||||
/// #[function_component(UseRef)]
|
||||
/// #[component(UseRef)]
|
||||
/// fn ref_hook() -> Html {
|
||||
/// let message = use_state(|| "".to_string());
|
||||
/// let message_count = use_mut_ref(|| 0);
|
||||
@ -141,9 +141,9 @@ where
|
||||
/// use wasm_bindgen::prelude::Closure;
|
||||
/// use wasm_bindgen::JsCast;
|
||||
/// use web_sys::{Event, HtmlElement};
|
||||
/// use yew::{function_component, html, use_effect_with, use_node_ref, Html};
|
||||
/// use yew::{component, html, use_effect_with, use_node_ref, Html};
|
||||
///
|
||||
/// #[function_component(UseNodeRef)]
|
||||
/// #[component(UseNodeRef)]
|
||||
/// pub fn node_ref_hook() -> Html {
|
||||
/// let div_ref = use_node_ref();
|
||||
///
|
||||
|
||||
@ -40,7 +40,7 @@ where
|
||||
/// use yew::prelude::*;
|
||||
/// # use std::rc::Rc;
|
||||
///
|
||||
/// #[function_component(UseState)]
|
||||
/// #[component(UseState)]
|
||||
/// fn state() -> Html {
|
||||
/// let counter = use_state(|| 0);
|
||||
/// let onclick = {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//! Function components are a simplified version of normal components.
|
||||
//! They consist of a single function annotated with the attribute `#[function_component]`
|
||||
//! They consist of a single function annotated with the attribute `#[component]`
|
||||
//! that receives props and determines what should be rendered by returning [`Html`](crate::Html).
|
||||
//!
|
||||
//! Functions with the attribute have to return `Html` and may take a single parameter for the type
|
||||
@ -12,7 +12,7 @@
|
||||
//! ```rust
|
||||
//! # use yew::prelude::*;
|
||||
//! #
|
||||
//! #[function_component]
|
||||
//! #[component]
|
||||
//! fn HelloWorld() -> Html {
|
||||
//! html! { "Hello world" }
|
||||
//! }
|
||||
@ -40,7 +40,7 @@ pub use hooks::*;
|
||||
/// for props. Note that the function only receives a reference to the props.
|
||||
///
|
||||
/// When using this attribute you need to provide a name for the component:
|
||||
/// `#[function_component(ComponentName)]`.
|
||||
/// `#component(ComponentName)]`.
|
||||
/// The attribute will then automatically create a [`FunctionComponent`] with the given
|
||||
/// identifier which you can use like a normal component.
|
||||
///
|
||||
@ -53,13 +53,16 @@ pub use hooks::*;
|
||||
/// # text: String
|
||||
/// # }
|
||||
/// #
|
||||
/// #[function_component(NameOfComponent)]
|
||||
/// #[component(NameOfComponent)]
|
||||
/// pub fn component(props: &Props) -> Html {
|
||||
/// html! {
|
||||
/// <p>{ &props.text }</p>
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub use yew_macro::function_component as component;
|
||||
/// A re-export of [`component`](yew_macro::function_component) with the older name.
|
||||
#[deprecated(since = "0.22.0", note = "renamed to `#[component]")]
|
||||
pub use yew_macro::function_component;
|
||||
/// This attribute creates a user-defined hook from a normal Rust function.
|
||||
pub use yew_macro::hook;
|
||||
@ -310,7 +313,7 @@ pub trait FunctionProvider {
|
||||
///
|
||||
/// Function Components should not be implemented with this type directly.
|
||||
///
|
||||
/// Use the `#[function_component]` macro instead.
|
||||
/// Use the `#[component]` macro instead.
|
||||
#[doc(hidden)]
|
||||
pub struct FunctionComponent<T>
|
||||
where
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
//! Primitive Components & Properties Types
|
||||
|
||||
use crate::function_component;
|
||||
use crate::component;
|
||||
use crate::html::{BaseComponent, ChildrenProps, Html};
|
||||
|
||||
/// A Component to represent a component that does not exist in current implementation.
|
||||
@ -28,12 +28,12 @@ use crate::html::{BaseComponent, ChildrenProps, Html};
|
||||
/// use yew::prelude::*;
|
||||
/// # use yew::html::ChildrenProps;
|
||||
/// #
|
||||
/// # #[function_component]
|
||||
/// # #[component]
|
||||
/// # fn Comp(props: &ChildrenProps) -> Html {
|
||||
/// # Html::default()
|
||||
/// # }
|
||||
/// #
|
||||
/// # #[function_component]
|
||||
/// # #[component]
|
||||
/// # fn Provider(props: &ChildrenProps) -> Html {
|
||||
/// # let children = props.children.clone();
|
||||
/// #
|
||||
@ -44,7 +44,7 @@ use crate::html::{BaseComponent, ChildrenProps, Html};
|
||||
/// # type Provider3 = Provider;
|
||||
/// # type Provider4 = Provider;
|
||||
///
|
||||
/// #[function_component]
|
||||
/// #[component]
|
||||
/// fn ServerApp() -> Html {
|
||||
/// // The Server Side Rendering Application has 3 Providers.
|
||||
/// html! {
|
||||
@ -58,7 +58,7 @@ use crate::html::{BaseComponent, ChildrenProps, Html};
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// #[function_component]
|
||||
/// #[component]
|
||||
/// fn App() -> Html {
|
||||
/// // The Client Side Rendering Application has 4 Providers.
|
||||
/// html! {
|
||||
@ -85,12 +85,12 @@ use crate::html::{BaseComponent, ChildrenProps, Html};
|
||||
/// use yew::prelude::*;
|
||||
/// # use yew::html::{PhantomComponent, ChildrenProps};
|
||||
/// #
|
||||
/// # #[function_component]
|
||||
/// # #[component]
|
||||
/// # fn Comp(props: &ChildrenProps) -> Html {
|
||||
/// # Html::default()
|
||||
/// # }
|
||||
/// #
|
||||
/// # #[function_component]
|
||||
/// # #[component]
|
||||
/// # fn Provider(props: &ChildrenProps) -> Html {
|
||||
/// # let children = props.children.clone();
|
||||
/// #
|
||||
@ -101,7 +101,7 @@ use crate::html::{BaseComponent, ChildrenProps, Html};
|
||||
/// # type Provider3 = Provider;
|
||||
/// # type Provider4 = Provider;
|
||||
///
|
||||
/// #[function_component]
|
||||
/// #[component]
|
||||
/// fn ServerApp() -> Html {
|
||||
/// html! {
|
||||
/// <Provider1>
|
||||
@ -118,7 +118,7 @@ use crate::html::{BaseComponent, ChildrenProps, Html};
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// #[function_component]
|
||||
/// #[component]
|
||||
/// fn App() -> Html {
|
||||
/// html! {
|
||||
/// <Provider1>
|
||||
@ -137,7 +137,7 @@ use crate::html::{BaseComponent, ChildrenProps, Html};
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn PhantomComponent<T>(props: &ChildrenProps) -> Html
|
||||
where
|
||||
T: BaseComponent,
|
||||
|
||||
@ -73,7 +73,7 @@ impl<COMP: BaseComponent> Context<COMP> {
|
||||
/// The common base of both function components and struct components.
|
||||
///
|
||||
/// If you are taken here by doc links, you might be looking for [`Component`] or
|
||||
/// [`#[function_component]`](crate::functional::function_component).
|
||||
/// [`#[component]`](crate::functional::component).
|
||||
///
|
||||
/// We provide a blanket implementation of this trait for every member that implements
|
||||
/// [`Component`].
|
||||
@ -84,7 +84,7 @@ impl<COMP: BaseComponent> Context<COMP> {
|
||||
/// implementation.
|
||||
///
|
||||
/// You should used the [`Component`] trait or the
|
||||
/// [`#[function_component]`](crate::functional::function_component) macro to define your
|
||||
/// [`#[component]`](crate::functional::component) macro to define your
|
||||
/// components.
|
||||
pub trait BaseComponent: Sized + 'static {
|
||||
/// The Component's Message.
|
||||
|
||||
@ -367,7 +367,7 @@ mod test {
|
||||
pub footer: Children,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn App(props: &Props) -> Html {
|
||||
let Props {
|
||||
header,
|
||||
@ -405,7 +405,7 @@ mod test {
|
||||
fn test_vchild_to_children_with_props_compiles() {
|
||||
use crate::prelude::*;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn Comp() -> Html {
|
||||
Html::default()
|
||||
}
|
||||
@ -420,7 +420,7 @@ mod test {
|
||||
pub footer: ChildrenWithProps<Comp>,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn App(props: &Props) -> Html {
|
||||
let Props {
|
||||
header,
|
||||
@ -459,7 +459,7 @@ mod test {
|
||||
use crate::prelude::*;
|
||||
use crate::virtual_dom::VList;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Foo() -> Html {
|
||||
todo!()
|
||||
}
|
||||
@ -470,7 +470,7 @@ mod test {
|
||||
pub children: Html,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Child(_props: &ChildProps) -> Html {
|
||||
html!()
|
||||
}
|
||||
@ -480,7 +480,7 @@ mod test {
|
||||
pub children: VList,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Parent(_props: &ParentProps) -> Html {
|
||||
todo!()
|
||||
}
|
||||
@ -517,7 +517,7 @@ mod test {
|
||||
pub children: AttrValue,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Child(_props: &ChildProps) -> Html {
|
||||
html!()
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ mod feat_csr_ssr {
|
||||
#[cfg(feature = "hydration")]
|
||||
use crate::suspense::SuspensionHandle;
|
||||
use crate::virtual_dom::{VNode, VSuspense};
|
||||
use crate::{function_component, html};
|
||||
use crate::{component, html};
|
||||
|
||||
#[derive(Properties, PartialEq, Debug, Clone)]
|
||||
pub(crate) struct BaseSuspenseProps {
|
||||
@ -147,7 +147,7 @@ mod feat_csr_ssr {
|
||||
}
|
||||
|
||||
/// Suspend rendering and show a fallback UI until the underlying task completes.
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn Suspense(props: &SuspenseProps) -> Html {
|
||||
let SuspenseProps { children, fallback } = props.clone();
|
||||
|
||||
@ -171,10 +171,10 @@ pub use feat_csr_ssr::*;
|
||||
#[cfg(not(any(feature = "ssr", feature = "csr")))]
|
||||
mod feat_no_csr_ssr {
|
||||
use super::*;
|
||||
use crate::function_component;
|
||||
use crate::component;
|
||||
|
||||
/// Suspend rendering and show a fallback UI until the underlying task completes.
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn Suspense(_props: &SuspenseProps) -> Html {
|
||||
Html::default()
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ impl<T: fmt::Debug> fmt::Debug for UseFutureHandle<T> {
|
||||
/// action=query&origin=*&format=json&generator=search&\
|
||||
/// gsrnamespace=0&gsrlimit=5&gsrsearch='New_England_Patriots'";
|
||||
///
|
||||
/// #[function_component]
|
||||
/// #[component]
|
||||
/// fn WikipediaSearch() -> HtmlResult {
|
||||
/// let res = use_future(|| async { Request::get(URL).send().await?.text().await })?;
|
||||
/// let result_html = match *res {
|
||||
|
||||
@ -290,12 +290,12 @@ mod ssr_tests {
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Child(props: &ChildProps) -> Html {
|
||||
html! { <div>{"Hello, "}{&props.name}{"!"}</div> }
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
html! {
|
||||
<div>
|
||||
|
||||
@ -301,7 +301,7 @@ mod ssr_tests {
|
||||
#[cfg_attr(not(target_os = "wasi"), test)]
|
||||
#[cfg_attr(target_os = "wasi", test(flavor = "current_thread"))]
|
||||
async fn test_text_back_to_back() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
let s = "world";
|
||||
|
||||
@ -324,12 +324,12 @@ mod ssr_tests {
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Child(props: &ChildProps) -> Html {
|
||||
html! { <div>{"Hello, "}{&props.name}{"!"}</div> }
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
html! {
|
||||
<>
|
||||
|
||||
@ -124,13 +124,13 @@ mod ssr_tests {
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Child(props: &ChildProps) -> HtmlResult {
|
||||
use_sleep()?;
|
||||
Ok(html! { <div>{"Hello, "}{&props.name}{"!"}</div> })
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
let fallback = html! {"loading..."};
|
||||
|
||||
|
||||
@ -573,7 +573,7 @@ mod ssr_tests {
|
||||
#[cfg_attr(not(target_os = "wasi"), test)]
|
||||
#[cfg_attr(target_os = "wasi", test(flavor = "current_thread"))]
|
||||
async fn test_simple_tag() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
html! { <div></div> }
|
||||
}
|
||||
@ -589,7 +589,7 @@ mod ssr_tests {
|
||||
#[cfg_attr(not(target_os = "wasi"), test)]
|
||||
#[cfg_attr(target_os = "wasi", test(flavor = "current_thread"))]
|
||||
async fn test_simple_tag_with_attr() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
html! { <div class="abc"></div> }
|
||||
}
|
||||
@ -605,7 +605,7 @@ mod ssr_tests {
|
||||
#[cfg_attr(not(target_os = "wasi"), test)]
|
||||
#[cfg_attr(target_os = "wasi", test(flavor = "current_thread"))]
|
||||
async fn test_simple_tag_with_content() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
html! { <div>{"Hello!"}</div> }
|
||||
}
|
||||
@ -621,7 +621,7 @@ mod ssr_tests {
|
||||
#[cfg_attr(not(target_os = "wasi"), test)]
|
||||
#[cfg_attr(target_os = "wasi", test(flavor = "current_thread"))]
|
||||
async fn test_simple_tag_with_nested_tag_and_input() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
html! { <div>{"Hello!"}<input value="abc" type="text" /></div> }
|
||||
}
|
||||
@ -637,7 +637,7 @@ mod ssr_tests {
|
||||
#[cfg_attr(not(target_os = "wasi"), test)]
|
||||
#[cfg_attr(target_os = "wasi", test(flavor = "current_thread"))]
|
||||
async fn test_textarea() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
html! { <textarea value="teststring" /> }
|
||||
}
|
||||
@ -653,7 +653,7 @@ mod ssr_tests {
|
||||
#[cfg_attr(not(target_os = "wasi"), test)]
|
||||
#[cfg_attr(target_os = "wasi", test(flavor = "current_thread"))]
|
||||
async fn test_textarea_w_defaultvalue() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
html! { <textarea defaultvalue="teststring" /> }
|
||||
}
|
||||
@ -669,7 +669,7 @@ mod ssr_tests {
|
||||
#[cfg_attr(not(target_os = "wasi"), test)]
|
||||
#[cfg_attr(target_os = "wasi", test(flavor = "current_thread"))]
|
||||
async fn test_value_precedence_over_defaultvalue() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
html! { <textarea defaultvalue="defaultvalue" value="value" /> }
|
||||
}
|
||||
@ -685,7 +685,7 @@ mod ssr_tests {
|
||||
#[cfg_attr(not(target_os = "wasi"), test)]
|
||||
#[cfg_attr(target_os = "wasi", test(flavor = "current_thread"))]
|
||||
async fn test_escaping_in_style_tag() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
html! { <style>{"body > a {color: #cc0;}"}</style> }
|
||||
}
|
||||
@ -701,7 +701,7 @@ mod ssr_tests {
|
||||
#[cfg_attr(not(target_os = "wasi"), test)]
|
||||
#[cfg_attr(target_os = "wasi", test(flavor = "current_thread"))]
|
||||
async fn test_escaping_in_script_tag() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
html! { <script>{"foo.bar = x < y;"}</script> }
|
||||
}
|
||||
@ -717,7 +717,7 @@ mod ssr_tests {
|
||||
#[cfg_attr(not(target_os = "wasi"), test)]
|
||||
#[cfg_attr(target_os = "wasi", test(flavor = "current_thread"))]
|
||||
async fn test_multiple_vtext_in_style_tag() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
let one = "html { background: black } ";
|
||||
let two = "body > a { color: white } ";
|
||||
|
||||
@ -80,7 +80,7 @@ mod ssr_tests {
|
||||
#[cfg_attr(not(target_os = "wasi"), test)]
|
||||
#[cfg_attr(target_os = "wasi", test(flavor = "current_thread"))]
|
||||
async fn test_simple_str() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
html! { "abc" }
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ use yew::platform::time::sleep;
|
||||
use yew::prelude::*;
|
||||
use yew::suspense::{use_future, Suspension, SuspensionResult};
|
||||
use yew::virtual_dom::VNode;
|
||||
use yew::{function_component, Renderer, ServerRenderer};
|
||||
use yew::{component, Renderer, ServerRenderer};
|
||||
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
@ -25,7 +25,7 @@ wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn hydration_works() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> Html {
|
||||
let ctr = use_state_eq(|| 0);
|
||||
|
||||
@ -45,7 +45,7 @@ async fn hydration_works() {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
html! {
|
||||
<div>
|
||||
@ -97,7 +97,7 @@ async fn hydration_works() {
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn hydration_with_raw() {
|
||||
#[function_component(Content)]
|
||||
#[component(Content)]
|
||||
fn content() -> Html {
|
||||
let vnode = VNode::from_html_unchecked("<div><p>Hello World</p></div>".into());
|
||||
|
||||
@ -108,7 +108,7 @@ async fn hydration_with_raw() {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
fn app() -> Html {
|
||||
html! {
|
||||
<div id="result">
|
||||
@ -189,7 +189,7 @@ async fn hydration_with_suspense() {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(Content)]
|
||||
#[component(Content)]
|
||||
fn content() -> HtmlResult {
|
||||
let resleep = use_sleep()?;
|
||||
|
||||
@ -216,7 +216,7 @@ async fn hydration_with_suspense() {
|
||||
})
|
||||
}
|
||||
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
fn app() -> Html {
|
||||
let fallback = html! {<div>{"wait..."}</div>};
|
||||
|
||||
@ -344,7 +344,7 @@ async fn hydration_with_suspense_not_suspended_at_start() {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(Content)]
|
||||
#[component(Content)]
|
||||
fn content() -> HtmlResult {
|
||||
let resleep = use_sleep()?;
|
||||
|
||||
@ -372,7 +372,7 @@ async fn hydration_with_suspense_not_suspended_at_start() {
|
||||
})
|
||||
}
|
||||
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
fn app() -> Html {
|
||||
let fallback = html! {<div>{"wait..."}</div>};
|
||||
|
||||
@ -468,7 +468,7 @@ async fn hydration_nested_suspense_works() {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(InnerContent)]
|
||||
#[component(InnerContent)]
|
||||
fn inner_content() -> HtmlResult {
|
||||
let resleep = use_sleep()?;
|
||||
|
||||
@ -483,7 +483,7 @@ async fn hydration_nested_suspense_works() {
|
||||
})
|
||||
}
|
||||
|
||||
#[function_component(Content)]
|
||||
#[component(Content)]
|
||||
fn content() -> HtmlResult {
|
||||
let resleep = use_sleep()?;
|
||||
|
||||
@ -503,7 +503,7 @@ async fn hydration_nested_suspense_works() {
|
||||
})
|
||||
}
|
||||
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
fn app() -> Html {
|
||||
let fallback = html! {<div>{"wait...(outer)"}</div>};
|
||||
|
||||
@ -602,7 +602,7 @@ async fn hydration_nested_suspense_works() {
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn hydration_node_ref_works() {
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
pub fn app() -> Html {
|
||||
let size = use_state(|| 4);
|
||||
|
||||
@ -625,20 +625,20 @@ async fn hydration_node_ref_works() {
|
||||
size: u32,
|
||||
}
|
||||
|
||||
#[function_component(Test1)]
|
||||
#[component(Test1)]
|
||||
fn test1() -> Html {
|
||||
html! {
|
||||
<span>{"test"}</span>
|
||||
}
|
||||
}
|
||||
#[function_component(Test2)]
|
||||
#[component(Test2)]
|
||||
fn test2() -> Html {
|
||||
html! {
|
||||
<Test1/>
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(List)]
|
||||
#[component(List)]
|
||||
fn list(props: &ListProps) -> Html {
|
||||
let elems = 0..props.size;
|
||||
|
||||
@ -693,7 +693,7 @@ async fn hydration_node_ref_works() {
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn hydration_list_order_works() {
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
pub fn app() -> Html {
|
||||
let elems = 0..10;
|
||||
|
||||
@ -713,20 +713,20 @@ async fn hydration_list_order_works() {
|
||||
number: u32,
|
||||
}
|
||||
|
||||
#[function_component(Number)]
|
||||
#[component(Number)]
|
||||
fn number(props: &NumberProps) -> Html {
|
||||
html! {
|
||||
<div>{props.number.to_string()}</div>
|
||||
}
|
||||
}
|
||||
#[function_component(SuspendedNumber)]
|
||||
#[component(SuspendedNumber)]
|
||||
fn suspended_number(props: &NumberProps) -> HtmlResult {
|
||||
use_suspend()?;
|
||||
Ok(html! {
|
||||
<div>{props.number.to_string()}</div>
|
||||
})
|
||||
}
|
||||
#[function_component(ToSuspendOrNot)]
|
||||
#[component(ToSuspendOrNot)]
|
||||
fn suspend_or_not(props: &NumberProps) -> Html {
|
||||
let number = props.number;
|
||||
html! {
|
||||
@ -776,7 +776,7 @@ async fn hydration_list_order_works() {
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn hydration_suspense_no_flickering() {
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
pub fn app() -> Html {
|
||||
let fallback = html! { <h1>{"Loading..."}</h1> };
|
||||
html! {
|
||||
@ -791,7 +791,7 @@ async fn hydration_suspense_no_flickering() {
|
||||
number: u32,
|
||||
}
|
||||
|
||||
#[function_component(SuspendedNumber)]
|
||||
#[component(SuspendedNumber)]
|
||||
fn suspended_number(props: &NumberProps) -> HtmlResult {
|
||||
use_suspend()?;
|
||||
|
||||
@ -799,7 +799,7 @@ async fn hydration_suspense_no_flickering() {
|
||||
<Number ..{props.clone()}/>
|
||||
})
|
||||
}
|
||||
#[function_component(Number)]
|
||||
#[component(Number)]
|
||||
fn number(props: &NumberProps) -> Html {
|
||||
html! {
|
||||
<div>
|
||||
@ -808,7 +808,7 @@ async fn hydration_suspense_no_flickering() {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(Suspended)]
|
||||
#[component(Suspended)]
|
||||
fn suspended() -> HtmlResult {
|
||||
use_suspend()?;
|
||||
|
||||
@ -886,7 +886,7 @@ async fn hydration_suspense_no_flickering() {
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn hydration_order_issue_nested_suspense() {
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
pub fn app() -> Html {
|
||||
let elems = (0..10).map(|number: u32| {
|
||||
html! {
|
||||
@ -906,14 +906,14 @@ async fn hydration_order_issue_nested_suspense() {
|
||||
number: u32,
|
||||
}
|
||||
|
||||
#[function_component(Number)]
|
||||
#[component(Number)]
|
||||
fn number(props: &NumberProps) -> Html {
|
||||
html! {
|
||||
<div>{props.number.to_string()}</div>
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(SuspendedNumber)]
|
||||
#[component(SuspendedNumber)]
|
||||
fn suspended_number(props: &NumberProps) -> HtmlResult {
|
||||
use_suspend()?;
|
||||
Ok(html! {
|
||||
@ -921,7 +921,7 @@ async fn hydration_order_issue_nested_suspense() {
|
||||
})
|
||||
}
|
||||
|
||||
#[function_component(ToSuspendOrNot)]
|
||||
#[component(ToSuspendOrNot)]
|
||||
fn suspend_or_not(props: &NumberProps) -> HtmlResult {
|
||||
let number = props.number;
|
||||
Ok(html! {
|
||||
@ -972,7 +972,7 @@ async fn hydration_order_issue_nested_suspense() {
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn hydration_props_blocked_until_hydrated() {
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
pub fn app() -> Html {
|
||||
let range = use_state(|| 0u32..2);
|
||||
{
|
||||
@ -995,7 +995,7 @@ async fn hydration_props_blocked_until_hydrated() {
|
||||
range: Range<u32>,
|
||||
}
|
||||
|
||||
#[function_component(ToSuspend)]
|
||||
#[component(ToSuspend)]
|
||||
fn to_suspend(ToSuspendProps { range }: &ToSuspendProps) -> HtmlResult {
|
||||
use_suspend(Duration::from_millis(100))?;
|
||||
Ok(html! {
|
||||
@ -1032,7 +1032,7 @@ async fn hydration_props_blocked_until_hydrated() {
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn hydrate_empty() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Updating() -> Html {
|
||||
let trigger = use_state(|| false);
|
||||
{
|
||||
@ -1048,11 +1048,11 @@ async fn hydrate_empty() {
|
||||
html! { <div>{"before"}</div> }
|
||||
}
|
||||
}
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Empty() -> Html {
|
||||
html! { <></> }
|
||||
}
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
html! {
|
||||
<>
|
||||
|
||||
@ -14,7 +14,7 @@ use yew::prelude::*;
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn change_nested_after_append() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Nested() -> Html {
|
||||
let delayed_trigger = use_state(|| true);
|
||||
|
||||
@ -36,12 +36,12 @@ async fn change_nested_after_append() {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Top() -> Html {
|
||||
html! { <Nested /> }
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
let show_bottom = use_state_eq(|| false);
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ async fn props_are_passed() {
|
||||
value: String,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn PropsComponent(props: &PropsPassedFunctionProps) -> Html {
|
||||
assert_eq!(&props.value, "props");
|
||||
html! {
|
||||
|
||||
@ -17,7 +17,7 @@ macro_rules! create_test {
|
||||
($name:ident, $raw:expr, $expected:expr) => {
|
||||
#[test]
|
||||
async fn $name() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
let raw = Html::from_html_unchecked(AttrValue::from($raw));
|
||||
html! {
|
||||
@ -78,7 +78,7 @@ macro_rules! create_update_html_test {
|
||||
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
|
||||
#[test]
|
||||
async fn $name() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
let raw_html = use_state(|| ($initial));
|
||||
let onclick = {
|
||||
@ -159,7 +159,7 @@ create_update_html_test!(
|
||||
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
|
||||
#[test]
|
||||
async fn change_vnode_types_from_other_to_vraw() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
let node = use_state(|| html!("text"));
|
||||
let onclick = {
|
||||
@ -211,7 +211,7 @@ async fn change_vnode_types_from_other_to_vraw() {
|
||||
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
|
||||
#[test]
|
||||
async fn change_vnode_types_from_vraw_to_other() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
let node = use_state(|| Html::from_html_unchecked(AttrValue::from("<span>second</span>")));
|
||||
let onclick = {
|
||||
|
||||
@ -58,7 +58,7 @@ async fn suspense_works() {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(Content)]
|
||||
#[component(Content)]
|
||||
fn content() -> HtmlResult {
|
||||
let resleep = use_sleep()?;
|
||||
|
||||
@ -85,7 +85,7 @@ async fn suspense_works() {
|
||||
})
|
||||
}
|
||||
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
fn app() -> Html {
|
||||
let fallback = html! {<div>{"wait..."}</div>};
|
||||
|
||||
@ -207,7 +207,7 @@ async fn suspense_not_suspended_at_start() {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(Content)]
|
||||
#[component(Content)]
|
||||
fn content() -> HtmlResult {
|
||||
let resleep = use_sleep()?;
|
||||
|
||||
@ -235,7 +235,7 @@ async fn suspense_not_suspended_at_start() {
|
||||
})
|
||||
}
|
||||
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
fn app() -> Html {
|
||||
let fallback = html! {<div>{"wait..."}</div>};
|
||||
|
||||
@ -319,7 +319,7 @@ async fn suspense_nested_suspense_works() {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(InnerContent)]
|
||||
#[component(InnerContent)]
|
||||
fn inner_content() -> HtmlResult {
|
||||
let resleep = use_sleep()?;
|
||||
|
||||
@ -334,7 +334,7 @@ async fn suspense_nested_suspense_works() {
|
||||
})
|
||||
}
|
||||
|
||||
#[function_component(Content)]
|
||||
#[component(Content)]
|
||||
fn content() -> HtmlResult {
|
||||
let resleep = use_sleep()?;
|
||||
|
||||
@ -354,7 +354,7 @@ async fn suspense_nested_suspense_works() {
|
||||
})
|
||||
}
|
||||
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
fn app() -> Html {
|
||||
let fallback = html! {<div>{"wait...(outer)"}</div>};
|
||||
|
||||
@ -465,7 +465,7 @@ async fn effects_not_run_when_suspended() {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(Content)]
|
||||
#[component(Content)]
|
||||
fn content(props: &Props) -> HtmlResult {
|
||||
{
|
||||
let counter = props.counter.clone();
|
||||
@ -504,7 +504,7 @@ async fn effects_not_run_when_suspended() {
|
||||
})
|
||||
}
|
||||
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
fn app(props: &Props) -> Html {
|
||||
let fallback = html! {<div>{"wait..."}</div>};
|
||||
|
||||
@ -597,7 +597,7 @@ async fn effects_not_run_when_suspended() {
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn use_suspending_future_works() {
|
||||
#[function_component(Content)]
|
||||
#[component(Content)]
|
||||
fn content() -> HtmlResult {
|
||||
let _sleep_handle = use_future(|| async move {
|
||||
sleep(Duration::from_millis(50)).await;
|
||||
@ -610,7 +610,7 @@ async fn use_suspending_future_works() {
|
||||
})
|
||||
}
|
||||
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
fn app() -> Html {
|
||||
let fallback = html! {<div>{"wait..."}</div>};
|
||||
|
||||
@ -643,7 +643,7 @@ async fn use_suspending_future_with_deps_works() {
|
||||
delay_millis: u64,
|
||||
}
|
||||
|
||||
#[function_component(Content)]
|
||||
#[component(Content)]
|
||||
fn content(ContentProps { delay_millis }: &ContentProps) -> HtmlResult {
|
||||
let delayed_result = use_future_with(*delay_millis, |delay_millis| async move {
|
||||
sleep(Duration::from_millis(*delay_millis)).await;
|
||||
@ -657,7 +657,7 @@ async fn use_suspending_future_with_deps_works() {
|
||||
})
|
||||
}
|
||||
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
fn app() -> Html {
|
||||
let fallback = html! {<div>{"wait..."}</div>};
|
||||
|
||||
@ -687,14 +687,14 @@ async fn use_suspending_future_with_deps_works() {
|
||||
async fn test_suspend_forever() {
|
||||
/// A component that its suspension never resumes.
|
||||
/// We test that this can be used with to trigger a suspension and unsuspend upon unmount.
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn SuspendForever() -> HtmlResult {
|
||||
let (s, handle) = Suspension::new();
|
||||
use_state(move || handle);
|
||||
Err(s.into())
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
let page = use_state(|| 1);
|
||||
|
||||
@ -737,7 +737,7 @@ async fn resume_after_unmount() {
|
||||
state: UseStateHandle<bool>,
|
||||
}
|
||||
|
||||
#[function_component(Content)]
|
||||
#[component(Content)]
|
||||
fn content(ContentProps { state }: &ContentProps) -> HtmlResult {
|
||||
let state = state.clone();
|
||||
let _sleep_handle = use_future(|| async move {
|
||||
@ -751,7 +751,7 @@ async fn resume_after_unmount() {
|
||||
})
|
||||
}
|
||||
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
fn app() -> Html {
|
||||
let fallback = html! {<div>{"wait..."}</div>};
|
||||
let state = use_state(|| true);
|
||||
@ -785,7 +785,7 @@ async fn resume_after_unmount() {
|
||||
async fn test_duplicate_suspension() {
|
||||
use yew::html::ChildrenProps;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn FetchingProvider(props: &ChildrenProps) -> HtmlResult {
|
||||
use_future(|| async {
|
||||
sleep(Duration::ZERO).await;
|
||||
@ -793,12 +793,12 @@ async fn test_duplicate_suspension() {
|
||||
Ok(html! { <>{props.children.clone()}</> })
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Child() -> Html {
|
||||
html! {<div id="result">{"hello!"}</div>}
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
let fallback = Html::default();
|
||||
html! {
|
||||
|
||||
@ -20,7 +20,7 @@ async fn use_callback_works() {
|
||||
callback: Callback<String, String>,
|
||||
}
|
||||
|
||||
#[function_component(MyComponent)]
|
||||
#[component(MyComponent)]
|
||||
fn my_component(props: &Props) -> Html {
|
||||
let greeting = props.callback.emit("Yew".to_string());
|
||||
|
||||
@ -39,7 +39,7 @@ async fn use_callback_works() {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(UseCallbackComponent)]
|
||||
#[component(UseCallbackComponent)]
|
||||
fn use_callback_comp() -> Html {
|
||||
let state = use_state(|| 0);
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ async fn use_context_scoping_works() {
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct ExampleContext(String);
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn ExpectNoContextComponent() -> Html {
|
||||
let example_context = use_context::<ExampleContext>();
|
||||
|
||||
@ -32,7 +32,7 @@ async fn use_context_scoping_works() {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn UseContextComponent() -> Html {
|
||||
type ExampleContextProvider = ContextProvider<ExampleContext>;
|
||||
html! {
|
||||
@ -56,7 +56,7 @@ async fn use_context_scoping_works() {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn UseContextComponentInner() -> Html {
|
||||
let context = use_context::<ExampleContext>();
|
||||
html! {
|
||||
@ -82,7 +82,7 @@ async fn use_context_works_with_multiple_types() {
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct ContextB(u32);
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Test1() -> Html {
|
||||
let ctx_a = use_context::<ContextA>();
|
||||
let ctx_b = use_context::<ContextB>();
|
||||
@ -93,7 +93,7 @@ async fn use_context_works_with_multiple_types() {
|
||||
html! {}
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Test2() -> Html {
|
||||
let ctx_a = use_context::<ContextA>();
|
||||
let ctx_b = use_context::<ContextB>();
|
||||
@ -104,7 +104,7 @@ async fn use_context_works_with_multiple_types() {
|
||||
html! {}
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Test3() -> Html {
|
||||
let ctx_a = use_context::<ContextA>();
|
||||
let ctx_b = use_context::<ContextB>();
|
||||
@ -115,7 +115,7 @@ async fn use_context_works_with_multiple_types() {
|
||||
html! {}
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Test4() -> Html {
|
||||
let ctx_a = use_context::<ContextA>();
|
||||
let ctx_b = use_context::<ContextB>();
|
||||
@ -126,7 +126,7 @@ async fn use_context_works_with_multiple_types() {
|
||||
html! {}
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn TestComponent() -> Html {
|
||||
type ContextAProvider = ContextProvider<ContextA>;
|
||||
type ContextBProvider = ContextProvider<ContextB>;
|
||||
@ -166,7 +166,7 @@ async fn use_context_update_works() {
|
||||
children: Children,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn RenderCounter(props: &RenderCounterProps) -> Html {
|
||||
let counter = use_mut_ref(|| 0);
|
||||
*counter.borrow_mut() += 1;
|
||||
@ -187,7 +187,7 @@ async fn use_context_update_works() {
|
||||
magic: usize,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn ContextOutlet(props: &ContextOutletProps) -> Html {
|
||||
let counter = use_mut_ref(|| 0);
|
||||
*counter.borrow_mut() += 1;
|
||||
@ -204,7 +204,7 @@ async fn use_context_update_works() {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn TestComponent() -> Html {
|
||||
type MyContextProvider = ContextProvider<Rc<MyContext>>;
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ async fn use_effect_destroys_on_component_drop() {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(UseEffectComponent)]
|
||||
#[component(UseEffectComponent)]
|
||||
fn use_effect_comp(props: &FunctionProps) -> Html {
|
||||
let effect_called = props.effect_called.clone();
|
||||
let destroy_called = props.destroy_called.clone();
|
||||
@ -47,7 +47,7 @@ async fn use_effect_destroys_on_component_drop() {
|
||||
html! {}
|
||||
}
|
||||
|
||||
#[function_component(UseEffectWrapperComponent)]
|
||||
#[component(UseEffectWrapperComponent)]
|
||||
fn use_effect_wrapper_comp(props: &WrapperProps) -> Html {
|
||||
let show = use_state(|| true);
|
||||
if *show {
|
||||
@ -79,7 +79,7 @@ async fn use_effect_destroys_on_component_drop() {
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn use_effect_works_many_times() {
|
||||
#[function_component(UseEffectComponent)]
|
||||
#[component(UseEffectComponent)]
|
||||
fn use_effect_comp() -> Html {
|
||||
let counter = use_state(|| 0);
|
||||
let counter_clone = counter.clone();
|
||||
@ -112,7 +112,7 @@ async fn use_effect_works_many_times() {
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn use_effect_works_once() {
|
||||
#[function_component(UseEffectComponent)]
|
||||
#[component(UseEffectComponent)]
|
||||
fn use_effect_comp() -> Html {
|
||||
let counter = use_state(|| 0);
|
||||
let counter_clone = counter.clone();
|
||||
@ -144,7 +144,7 @@ async fn use_effect_works_once() {
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn use_effect_refires_on_dependency_change() {
|
||||
#[function_component(UseEffectComponent)]
|
||||
#[component(UseEffectComponent)]
|
||||
fn use_effect_comp() -> Html {
|
||||
let number_ref = use_mut_ref(|| 0);
|
||||
let number_ref_c = number_ref.clone();
|
||||
|
||||
@ -15,7 +15,7 @@ wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn use_memo_works() {
|
||||
#[function_component(UseMemoComponent)]
|
||||
#[component(UseMemoComponent)]
|
||||
fn use_memo_comp() -> Html {
|
||||
let state = use_state(|| 0);
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn use_prepared_state_works() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> HtmlResult {
|
||||
let ctr = use_prepared_state!((), |_| -> u32 { 12345 })?.unwrap_or_default();
|
||||
|
||||
@ -27,7 +27,7 @@ async fn use_prepared_state_works() {
|
||||
})
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
html! {
|
||||
<Suspense fallback={Html::default()}>
|
||||
@ -66,7 +66,7 @@ async fn use_prepared_state_works() {
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn use_prepared_state_with_suspension_works() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> HtmlResult {
|
||||
let ctr = use_prepared_state!((), async move |_| -> u32 { 12345 })?.unwrap_or_default();
|
||||
|
||||
@ -77,7 +77,7 @@ async fn use_prepared_state_with_suspension_works() {
|
||||
})
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
html! {
|
||||
<Suspense fallback={Html::default()}>
|
||||
|
||||
@ -35,7 +35,7 @@ impl Reducible for CounterState {
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn use_reducer_works() {
|
||||
#[function_component(UseReducerComponent)]
|
||||
#[component(UseReducerComponent)]
|
||||
fn use_reducer_comp() -> Html {
|
||||
let counter = use_reducer(|| CounterState { counter: 10 });
|
||||
|
||||
@ -80,7 +80,7 @@ impl Reducible for ContentState {
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn use_reducer_eq_works() {
|
||||
#[function_component(UseReducerComponent)]
|
||||
#[component(UseReducerComponent)]
|
||||
fn use_reducer_comp() -> Html {
|
||||
let content = use_reducer_eq(|| ContentState {
|
||||
content: HashSet::default(),
|
||||
|
||||
@ -14,7 +14,7 @@ wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn use_ref_works() {
|
||||
#[function_component(UseRefComponent)]
|
||||
#[component(UseRefComponent)]
|
||||
fn use_ref_comp() -> Html {
|
||||
let ref_example = use_mut_ref(|| 0);
|
||||
*ref_example.borrow_mut().deref_mut() += 1;
|
||||
|
||||
@ -13,7 +13,7 @@ wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn use_state_works() {
|
||||
#[function_component(UseComponent)]
|
||||
#[component(UseComponent)]
|
||||
fn use_state_comp() -> Html {
|
||||
let counter = use_state(|| 0);
|
||||
if *counter < 5 {
|
||||
@ -39,7 +39,7 @@ async fn use_state_works() {
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn multiple_use_state_setters() {
|
||||
#[function_component(UseComponent)]
|
||||
#[component(UseComponent)]
|
||||
fn use_state_comp() -> Html {
|
||||
let counter = use_state(|| 0);
|
||||
let counter_clone = counter.clone();
|
||||
@ -82,7 +82,7 @@ async fn use_state_eq_works() {
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
static RENDER_COUNT: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
#[function_component(UseComponent)]
|
||||
#[component(UseComponent)]
|
||||
fn use_state_comp() -> Html {
|
||||
RENDER_COUNT.fetch_add(1, Ordering::Relaxed);
|
||||
let counter = use_state_eq(|| 0);
|
||||
|
||||
@ -15,7 +15,7 @@ wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn use_transitive_state_works() {
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Comp() -> HtmlResult {
|
||||
let ctr = use_transitive_state!((), |_| -> u32 { 12345 })?.unwrap_or_default();
|
||||
|
||||
@ -26,7 +26,7 @@ async fn use_transitive_state_works() {
|
||||
})
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
html! {
|
||||
<Suspense fallback={Html::default()}>
|
||||
|
||||
@ -115,7 +115,7 @@ pub struct ListItemProps {
|
||||
value: String,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn ListItem(props: &ListItemProps) -> Html {
|
||||
let ListItemProps { value } = props.clone();
|
||||
html! {
|
||||
@ -130,7 +130,7 @@ pub struct Props {
|
||||
pub children: ChildrenWithProps<ListItem>,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn List(props: &Props) -> Html {
|
||||
let modified_children = props.children.iter().map(|mut item| {
|
||||
let mut props = Rc::make_mut(&mut item.props);
|
||||
|
||||
@ -31,7 +31,7 @@ pub struct ModalProps {
|
||||
pub children: Html,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Modal(props: &ModalProps) -> Html {
|
||||
let modal_host = gloo::utils::document()
|
||||
.get_element_by_id("modal_host")
|
||||
|
||||
@ -34,7 +34,7 @@ to render `<App />` into a `String`.
|
||||
use yew::prelude::*;
|
||||
use yew::ServerRenderer;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
html! {<div>{"Hello, World!"}</div>}
|
||||
}
|
||||
@ -178,7 +178,7 @@ until `rendered()` method is called.
|
||||
use yew::prelude::*;
|
||||
use yew::Renderer;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
html! {<div>{"Hello, World!"}</div>}
|
||||
}
|
||||
@ -206,7 +206,7 @@ Yew supports single thread mode for server-side rendering by `yew::LocalServerRe
|
||||
use yew::prelude::*;
|
||||
use yew::LocalServerRenderer;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
use yew_router::prelude::*;
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ struct Theme {
|
||||
background: String,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn App() -> Html {
|
||||
let ctx = use_state(|| Theme {
|
||||
foreground: "#000000".to_owned(),
|
||||
@ -38,7 +38,7 @@ pub fn App() -> Html {
|
||||
}
|
||||
|
||||
// highlight-start
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn ThemedButtonHOC() -> Html {
|
||||
let theme = use_context::<Theme>().expect("no ctx found");
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ This situation is called "Prop Drilling".
|
||||
Consider the following example which passes down the theme using props:
|
||||
|
||||
```rust
|
||||
use yew::{html, Component, Context, Html, Properties, function_component};
|
||||
use yew::{html, Component, Context, Html, Properties, component};
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct Theme {
|
||||
@ -34,7 +34,7 @@ pub struct NavbarProps {
|
||||
theme: Theme,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Navbar(props: &NavbarProps) -> Html {
|
||||
html! {
|
||||
<div>
|
||||
@ -54,14 +54,14 @@ pub struct ThemeProps {
|
||||
children: Html,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Title(_props: &ThemeProps) -> Html {
|
||||
html! {
|
||||
// impl
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn NavButton(_props: &ThemeProps) -> Html {
|
||||
html! {
|
||||
// impl
|
||||
@ -69,7 +69,7 @@ fn NavButton(_props: &ThemeProps) -> Html {
|
||||
}
|
||||
|
||||
/// App root
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
let theme = Theme {
|
||||
foreground: "yellow".to_owned(),
|
||||
@ -107,7 +107,7 @@ struct Theme {
|
||||
}
|
||||
|
||||
/// Main component
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn App() -> Html {
|
||||
let ctx = use_state(|| Theme {
|
||||
foreground: "#000000".to_owned(),
|
||||
@ -127,7 +127,7 @@ pub fn App() -> Html {
|
||||
|
||||
/// The toolbar.
|
||||
/// This component has access to the context
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn Toolbar() -> Html {
|
||||
html! {
|
||||
<div>
|
||||
@ -139,7 +139,7 @@ pub fn Toolbar() -> Html {
|
||||
/// Button placed in `Toolbar`.
|
||||
/// As this component is a child of `ThemeContextProvider` in the component tree, it also has access
|
||||
/// to the context.
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn ThemedButton() -> Html {
|
||||
let theme = use_context::<Theme>().expect("no ctx found");
|
||||
|
||||
|
||||
@ -23,14 +23,14 @@ let result = cb.emit(String::from("Bob")); // call the callback
|
||||
A common pattern in yew is to create a callback and pass it down as a prop.
|
||||
|
||||
```rust
|
||||
use yew::{function_component, html, Html, Properties, Callback};
|
||||
use yew::{component, html, Html, Properties, Callback};
|
||||
|
||||
#[derive(Properties, PartialEq)]
|
||||
pub struct Props {
|
||||
pub on_name_entry: Callback<String>,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn HelloWorld(props: &Props) -> Html {
|
||||
|
||||
props.on_name_entry.emit(String::from("Bob"));
|
||||
@ -39,7 +39,7 @@ fn HelloWorld(props: &Props) -> Html {
|
||||
}
|
||||
|
||||
// Then supply the prop
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
let on_name_entry: Callback<String> = Callback::from(move |name: String| {
|
||||
let greeting = format!("Hey, {}!", name);
|
||||
@ -58,9 +58,9 @@ Callbacks are also used to hook into DOM events.
|
||||
For example, here we define a callback that will be called when the user clicks the button:
|
||||
|
||||
```rust
|
||||
use yew::{function_component, html, Html, Properties, Callback};
|
||||
use yew::{component, html, Html, Properties, Callback};
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
let onclick = Callback::from(move |_| {
|
||||
let greeting = String::from("Hi there");
|
||||
|
||||
@ -5,9 +5,9 @@ title: 'Children'
|
||||
`Children` is a special prop type that allows you to receive nested `Html` that is provided like html child elements.
|
||||
|
||||
```rust
|
||||
use yew::{function_component, html, Html, Properties};
|
||||
use yew::{component, html, Html, Properties};
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
html! {
|
||||
// highlight-start
|
||||
@ -25,7 +25,7 @@ pub struct Props {
|
||||
pub children: Html, // the field name `children` is important!
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn HelloWorld(props: &Props) -> Html {
|
||||
html! {
|
||||
<div class="very-stylized-container">
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
---
|
||||
title: 'Generic Components'
|
||||
description: 'The #[function_component] attribute'
|
||||
description: 'The #[component] attribute'
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs'
|
||||
import TabItem from '@theme/TabItem'
|
||||
|
||||
The `#[function_component]` attribute also works with generic functions for creating generic components.
|
||||
The `#[component]` attribute also works with generic functions for creating generic components.
|
||||
|
||||
```rust
|
||||
use std::fmt::Display;
|
||||
use yew::{function_component, html, Properties, Html};
|
||||
use yew::{component, html, Properties, Html};
|
||||
|
||||
#[derive(Properties, PartialEq)]
|
||||
pub struct Props<T>
|
||||
@ -20,7 +20,7 @@ where
|
||||
data: T,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
pub fn MyGenericComponent<T>(props: &Props<T>) -> Html
|
||||
where
|
||||
T: PartialEq + Clone + Into<Html>,
|
||||
|
||||
@ -16,7 +16,7 @@ use gloo::utils::window;
|
||||
use std::mem::drop;
|
||||
|
||||
|
||||
#[function_component(ShowStorageChanged)]
|
||||
#[component(ShowStorageChanged)]
|
||||
pub fn show_storage_changed() -> Html {
|
||||
let state_storage_changed = use_state(|| false);
|
||||
|
||||
|
||||
@ -31,20 +31,20 @@ They allow very detailed control, though you will not need that level of detail
|
||||
|
||||
## Creating function components
|
||||
|
||||
To create a function component add the `#[function_component]` attribute to a function.
|
||||
To create a function component add the `#[component]` attribute to a function.
|
||||
By convention, the function is named in PascalCase, like all components, to contrast its
|
||||
use to normal html elements inside the `html!` macro.
|
||||
|
||||
```rust
|
||||
use yew::{function_component, html, Html};
|
||||
use yew::{component, html, Html};
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn HelloWorld() -> Html {
|
||||
html! { "Hello world" }
|
||||
}
|
||||
|
||||
// Then somewhere else you can use the component inside `html!`
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
html! { <HelloWorld /> }
|
||||
}
|
||||
|
||||
@ -45,27 +45,27 @@ pub struct Props {
|
||||
|
||||
## Use in function components
|
||||
|
||||
The attribute `#[function_component]` allows to optionally receive Props in the function arguments. To supply them,
|
||||
The attribute `#[component]` allows to optionally receive Props in the function arguments. To supply them,
|
||||
they are assigned via attributes in the `html!` macro.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="with-props" label="With Props">
|
||||
|
||||
```rust
|
||||
use yew::{function_component, html, Html, Properties};
|
||||
use yew::{component, html, Html, Properties};
|
||||
|
||||
#[derive(Properties, PartialEq)]
|
||||
pub struct Props {
|
||||
pub is_loading: bool,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn HelloWorld(&Props { is_loading }: &Props) -> Html {
|
||||
html! { <>{"Am I loading? - "}{is_loading}</> }
|
||||
}
|
||||
|
||||
// Then supply the prop
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
html! { <HelloWorld is_loading=true /> }
|
||||
}
|
||||
@ -76,15 +76,15 @@ fn App() -> Html {
|
||||
<TabItem value="no-props" label="No Props">
|
||||
|
||||
```rust
|
||||
use yew::{function_component, html, Html};
|
||||
use yew::{component, html, Html};
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn HelloWorld() -> Html {
|
||||
html! { "Hello world" }
|
||||
}
|
||||
|
||||
// No props to supply
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
html! { <HelloWorld /> }
|
||||
}
|
||||
@ -110,7 +110,7 @@ The doc strings of your properties should mention whether a prop is optional and
|
||||
Initialize the prop value with the default value of the field's type using the `Default` trait.
|
||||
|
||||
```rust
|
||||
use yew::{function_component, html, Html, Properties};
|
||||
use yew::{component, html, Html, Properties};
|
||||
|
||||
#[derive(Properties, PartialEq)]
|
||||
pub struct Props {
|
||||
@ -120,7 +120,7 @@ pub struct Props {
|
||||
pub is_loading: bool,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn HelloWorld(&Props { is_loading }: &Props) -> Html {
|
||||
if is_loading {
|
||||
html! { "Loading" }
|
||||
@ -130,12 +130,12 @@ fn HelloWorld(&Props { is_loading }: &Props) -> Html {
|
||||
}
|
||||
|
||||
// Then use like this with default
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Case1() -> Html {
|
||||
html! { <HelloWorld /> }
|
||||
}
|
||||
// Or no override the default
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Case2() -> Html {
|
||||
html! { <HelloWorld is_loading=true /> }
|
||||
}
|
||||
@ -161,7 +161,7 @@ pub struct Props {
|
||||
pub name: AttrValue,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Hello(&Props { is_loading, ref name }: &Props) -> Html {
|
||||
if is_loading {
|
||||
html! { "Loading" }
|
||||
@ -171,12 +171,12 @@ fn Hello(&Props { is_loading, ref name }: &Props) -> Html {
|
||||
}
|
||||
|
||||
// Then use like this with default
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Case1() -> Html {
|
||||
html! { <Hello /> }
|
||||
}
|
||||
// Or no override the default
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Case2() -> Html {
|
||||
html! { <Hello name="Sam" /> }
|
||||
}
|
||||
@ -205,7 +205,7 @@ pub struct Props {
|
||||
pub name: AttrValue,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Hello(&Props { is_loading, ref name }: &Props) -> Html {
|
||||
if is_loading {
|
||||
html! { "Loading" }
|
||||
@ -215,12 +215,12 @@ fn Hello(&Props { is_loading, ref name }: &Props) -> Html {
|
||||
}
|
||||
|
||||
// Then use like this with default
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Case1() -> Html {
|
||||
html! { <Hello /> }
|
||||
}
|
||||
// Or no override the default
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Case2() -> Html {
|
||||
html! { <Hello name="Sam" /> }
|
||||
}
|
||||
@ -256,7 +256,7 @@ pub struct Props {
|
||||
pub name: AttrValue,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Hello(&Props { is_loading, ref name }: &Props) -> Html {
|
||||
if is_loading {
|
||||
html! { "Loading" }
|
||||
@ -265,7 +265,7 @@ fn Hello(&Props { is_loading, ref name }: &Props) -> Html {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
// highlight-start
|
||||
let pre_made_props = yew::props! {
|
||||
@ -286,9 +286,9 @@ generate the `Properties` struct for you.
|
||||
use yew::prelude::*;
|
||||
use yew_autoprops::autoprops;
|
||||
|
||||
// the #[autoprops] macro must appear BEFORE #[function_component], the order matters
|
||||
// the #[autoprops] macro must appear BEFORE #[component], the order matters
|
||||
#[autoprops]
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Greetings(
|
||||
#[prop_or_default]
|
||||
is_loading: bool,
|
||||
|
||||
@ -10,14 +10,14 @@ from its props when its view function does not mutate its state or has other sid
|
||||
The example below is a pure component. For a given prop `is_loading` it will always result in the same `Html` without any side effects.
|
||||
|
||||
```rust
|
||||
use yew::{Properties, function_component, Html, html};
|
||||
use yew::{Properties, component, Html, html};
|
||||
|
||||
#[derive(Properties, PartialEq)]
|
||||
pub struct Props {
|
||||
pub is_loading: bool,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn HelloWorld(props: &Props) -> Html {
|
||||
if props.is_loading {
|
||||
html! { "Loading" }
|
||||
|
||||
@ -105,7 +105,7 @@ struct Props {
|
||||
children: Html,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn MyComponent(props: &Props) -> Html {
|
||||
let Props {
|
||||
class,
|
||||
|
||||
@ -10,7 +10,7 @@ Components can be used in the `html!` macro:
|
||||
```rust
|
||||
use yew::prelude::*;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn MyComponent() -> Html {
|
||||
html! {
|
||||
{ "This component has no properties!" }
|
||||
@ -23,7 +23,7 @@ struct Props {
|
||||
user_last_name: String,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn MyComponentWithProps(props: &Props) -> Html {
|
||||
let Props { user_first_name, user_last_name } = props;
|
||||
html! {
|
||||
@ -66,7 +66,7 @@ struct Props {
|
||||
children: Html,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Container(props: &Props) -> Html {
|
||||
html! {
|
||||
<div id={props.id.clone()}>
|
||||
@ -97,7 +97,7 @@ struct Props {
|
||||
children: Html,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn Container(props: &Props) -> Html {
|
||||
html! {
|
||||
<div id={props.id.clone()}>
|
||||
|
||||
@ -19,7 +19,7 @@ use web_sys::{Element, Node};
|
||||
use yew::prelude::*;
|
||||
use gloo::utils::document;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn MyComponent() -> Html {
|
||||
// memoize as this only needs to be executed once
|
||||
let node = use_memo(
|
||||
|
||||
@ -126,7 +126,7 @@ use wasm_bindgen::JsCast;
|
||||
use web_sys::{EventTarget, HtmlInputElement};
|
||||
use yew::prelude::*;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn MyComponent() -> Html {
|
||||
let input_value_handle = use_state(String::default);
|
||||
let input_value = (*input_value_handle).clone();
|
||||
@ -220,7 +220,7 @@ but it works in a very similar way to `JsCast`.
|
||||
use web_sys::HtmlInputElement;
|
||||
use yew::prelude::*;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn MyComponent() -> Html {
|
||||
let input_value_handle = use_state(String::default);
|
||||
let input_value = (*input_value_handle).clone();
|
||||
@ -280,7 +280,7 @@ does the cast on the target of the event. `TargetCast::target_unchecked_into` is
|
||||
use web_sys::HtmlInputElement;
|
||||
use yew::prelude::*;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn MyComponent() -> Html {
|
||||
//highlight-next-line
|
||||
let input_node_ref = use_node_ref();
|
||||
@ -328,7 +328,7 @@ You might also see by using `NodeRef` we don't have to send the `String` back in
|
||||
use web_sys::HtmlInputElement;
|
||||
use yew::prelude::*;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn MyComponent() -> Html {
|
||||
let input_node_ref = use_node_ref();
|
||||
|
||||
@ -390,7 +390,7 @@ use wasm_bindgen::{prelude::Closure, JsCast};
|
||||
use web_sys::HtmlElement;
|
||||
use yew::prelude::*;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn MyComponent() -> Html {
|
||||
let div_node_ref = use_node_ref();
|
||||
|
||||
@ -457,7 +457,7 @@ use yew::prelude::*;
|
||||
|
||||
use gloo::events::EventListener;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn MyComponent() -> Html {
|
||||
let div_node_ref = use_node_ref();
|
||||
|
||||
|
||||
@ -66,7 +66,7 @@ enum Route {
|
||||
NotFound,
|
||||
}
|
||||
|
||||
#[function_component(Secure)]
|
||||
#[component(Secure)]
|
||||
fn secure() -> Html {
|
||||
let navigator = use_navigator().unwrap();
|
||||
|
||||
@ -89,7 +89,7 @@ fn switch(routes: Route) -> Html {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(Main)]
|
||||
#[component(Main)]
|
||||
fn app() -> Html {
|
||||
html! {
|
||||
<BrowserRouter>
|
||||
@ -202,7 +202,7 @@ For function components, the `use_navigator` hook re-renders the component when
|
||||
Here is how to implement a button that navigates to the `Home` route when clicked.
|
||||
|
||||
```rust ,ignore
|
||||
#[function_component(MyComponent)]
|
||||
#[component(MyComponent)]
|
||||
pub fn my_component() -> Html {
|
||||
let navigator = use_navigator().unwrap();
|
||||
let onclick = Callback::from(move |_| navigator.push(&Route::Home));
|
||||
@ -232,7 +232,7 @@ implements `Clone`, here is for example how to have multiple buttons for differe
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
|
||||
#[function_component(NavItems)]
|
||||
#[component(NavItems)]
|
||||
pub fn nav_items() -> Html {
|
||||
let navigator = use_navigator().unwrap();
|
||||
|
||||
@ -292,7 +292,7 @@ navigator API. The component accepts a
|
||||
Here is an example:
|
||||
|
||||
```rust ,ignore
|
||||
#[function_component(SomePage)]
|
||||
#[component(SomePage)]
|
||||
fn some_page() -> Html {
|
||||
// made-up hook `use_user`
|
||||
let user = match use_user() {
|
||||
@ -471,7 +471,7 @@ fn switch_settings(route: SettingsRoute) -> Html {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
pub fn app() -> Html {
|
||||
html! {
|
||||
<BrowserRouter>
|
||||
|
||||
@ -24,14 +24,14 @@ The recommended way to use suspense is with hooks.
|
||||
```rust ,ignore
|
||||
use yew::prelude::*;
|
||||
|
||||
#[function_component(Content)]
|
||||
#[component(Content)]
|
||||
fn content() -> HtmlResult {
|
||||
let user = use_user()?;
|
||||
|
||||
Ok(html! {<div>{"Hello, "}{&user.name}</div>})
|
||||
}
|
||||
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
fn app() -> Html {
|
||||
let fallback = html! {<div>{"Loading..."}</div>};
|
||||
|
||||
@ -131,14 +131,14 @@ fn use_user() -> SuspensionResult<User> {
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(Content)]
|
||||
#[component(Content)]
|
||||
fn content() -> HtmlResult {
|
||||
let user = use_user()?;
|
||||
|
||||
Ok(html! {<div>{"Hello, "}{&user.name}</div>})
|
||||
}
|
||||
|
||||
#[function_component(App)]
|
||||
#[component(App)]
|
||||
fn app() -> Html {
|
||||
let fallback = html! {<div>{"Loading..."}</div>};
|
||||
|
||||
|
||||
@ -100,7 +100,7 @@ properties, you can instead use `yew::Renderer::<App>::with_props(..).render()`.
|
||||
```rust ,no_run, title=main.rs
|
||||
use yew::prelude::*;
|
||||
|
||||
#[function_component]
|
||||
#[component]
|
||||
fn App() -> Html {
|
||||
let counter = use_state(|| 0);
|
||||
let onclick = {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user