Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document html_nested! macro and add regression doc-tests for #1527 #1530

Merged
merged 5 commits into from
Aug 29, 2020
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 113 additions & 1 deletion yew/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,119 @@ extern crate self as yew;
/// This macro implements JSX-like templates.
pub use yew_macro::html;

#[doc(hidden)]
/// This macro is similar to [`html!`], but returns actual component type instead
/// of generic [`Html`].
Mingun marked this conversation as resolved.
Show resolved Hide resolved
///
/// That macro is useful when, for example, in typical implementation of `List`
Mingun marked this conversation as resolved.
Show resolved Hide resolved
/// component. In the typical implementation you have two connected components --
Mingun marked this conversation as resolved.
Show resolved Hide resolved
/// `List` and `ListItem`, and `List` allowing only `ListItem`s inside them.
Mingun marked this conversation as resolved.
Show resolved Hide resolved
/// Example of such component you can find in the [`nested_list`] example.
Mingun marked this conversation as resolved.
Show resolved Hide resolved
///
/// Manually you create list by just nesting `ListItem`'s into `List`:
///
/// ```
/// # use yew::prelude::*;
/// use yew::html::ChildrenRenderer;
/// use yew::virtual_dom::VChild;
///
/// #[derive(Clone, Properties)]
/// struct List {
/// children: ChildrenRenderer<ListItem>,
/// }
/// impl Component for List {
/// // ...
/// # type Message = ();
/// # type Properties = Self;
/// # fn create(props: Self::Properties, _: ComponentLink<Self>) -> Self { props }
/// # fn update(&mut self, _: Self::Message) -> ShouldRender { false }
/// # fn change(&mut self, _: Self::Properties) -> ShouldRender { false }
/// # fn view(&self) -> Html { unimplemented!() }
/// }
///
/// #[derive(Clone)]
/// struct ListItem;
/// impl Component for ListItem {
/// # type Message = ();
/// type Properties = ();
/// // ...
/// # fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self { Self }
/// # fn update(&mut self, _: Self::Message) -> ShouldRender { false }
/// # fn change(&mut self, _: Self::Properties) -> ShouldRender { false }
/// # fn view(&self) -> Html { unimplemented!() }
/// }
///
/// // Required for ChildrenRenderer
/// impl From<VChild<ListItem>> for ListItem {
/// fn from(child: VChild<ListItem>) -> Self { Self }
/// }
///
/// impl From<ListItem> for Html {
/// fn from(item: ListItem) -> Html { item.view() }
/// }
Mingun marked this conversation as resolved.
Show resolved Hide resolved
///
/// # fn test() -> Html {
/// html! {
/// <List>
/// <ListItem/>
/// <ListItem/>
/// <ListItem/>
/// </List>
/// }
/// # }
/// ```
///
/// But in most real cases you need to forming content of you list programmatically.
Mingun marked this conversation as resolved.
Show resolved Hide resolved
/// That's mean, that you would write code like this:
Mingun marked this conversation as resolved.
Show resolved Hide resolved
/// ```
/// # use yew::prelude::*;
/// # use yew::html::ChildrenRenderer;
/// # use yew::virtual_dom::VChild;
/// # #[derive(Clone, Properties)]
/// # struct List { children: ChildrenRenderer<ListItem> }
/// # impl Component for List {
/// # type Message = ();
/// # type Properties = Self;
/// # fn create(props: Self::Properties, _: ComponentLink<Self>) -> Self { props }
/// # fn update(&mut self, _: Self::Message) -> ShouldRender { false }
/// # fn change(&mut self, _: Self::Properties) -> ShouldRender { false }
/// # fn view(&self) -> Html { unimplemented!() }
/// # }
/// # #[derive(Clone)]
/// # struct ListItem;
/// # impl Component for ListItem {
/// # type Message = ();
/// # type Properties = ();
/// # fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self { Self }
/// # fn update(&mut self, _: Self::Message) -> ShouldRender { false }
/// # fn change(&mut self, _: Self::Properties) -> ShouldRender { false }
/// # fn view(&self) -> Html { unimplemented!() }
/// # }
/// # impl From<VChild<ListItem>> for ListItem {
/// # fn from(child: VChild<ListItem>) -> Self { Self }
/// # }
/// # impl From<ListItem> for Html {
/// # fn from(item: ListItem) -> Html { item.view() }
/// # }
/// # fn test() -> Html {
/// # let some_iter = (0..10);
/// html! {
/// <List>
/// { for some_iter.map(|_| html_nested!{ <ListItem/> }) }
/// </List>
/// }
/// # }
Mingun marked this conversation as resolved.
Show resolved Hide resolved
/// ```
///
/// If you used the [`html!`] macro instead of `html_nested!`, the code would
/// not be compiled because we explicitly indicated to the compiler that `List`
Mingun marked this conversation as resolved.
Show resolved Hide resolved
/// can only contain elements of type `ListItem` using [`ChildrenRenderer<ListItem>`],
/// while [`html!`] wraps their contents into [`Html`].
Mingun marked this conversation as resolved.
Show resolved Hide resolved
///
///
/// [`html!`]: ./macro.html.html
/// [`Html`]: ./html/type.Html.html
/// [`nested_list`]: https://github.com/yewstack/yew/tree/master/examples/nested_list
/// [`ChildrenRenderer<ListItem>`]: ./html/struct.ChildrenRenderer.html
pub use yew_macro::html_nested;

/// This module contains macros which implements html! macro and JSX-like templates
Expand Down