Skip to content

Commit

Permalink
rebase onto master
Browse files Browse the repository at this point in the history
  • Loading branch information
voidpumpkin committed Nov 20, 2021
1 parent 7907772 commit 8c41db3
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 84 deletions.
75 changes: 40 additions & 35 deletions examples/router/src/components/pagination.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
use serde::Deserialize;
use serde::Serialize;
use yew::prelude::*;
use yew_router::prelude::*;

use crate::Route;

const ELLIPSIS: &str = "\u{02026}";

#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
pub struct PageQuery {
pub page: u64,
}

#[derive(Clone, Debug, PartialEq, Properties)]
pub struct Props {
pub page: u64,
pub total_pages: u64,
pub on_switch_page: Callback<u64>,
pub route_to_page: Route,
}

pub struct Pagination;
Expand Down Expand Up @@ -34,18 +44,21 @@ impl Pagination {
fn render_link(&self, to_page: u64, props: &Props) -> Html {
let Props {
page,
ref on_switch_page,
route_to_page,
..
} = *props;
} = props.clone();

let onclick = on_switch_page.reform(move |_| to_page);
let is_current_class = if to_page == page { "is-current" } else { "" };

html! {
<li>
<a href="javascript:void(0)" class={classes!("pagination-link", is_current_class)} aria-label={format!("Goto page {}", to_page)} {onclick}>
<Link<Route, PageQuery>
classes={classes!("pagination-link", is_current_class)}
to={route_to_page}
query={Some(PageQuery{page: to_page})}
>
{ to_page }
</a>
</Link<Route, PageQuery>>
</li>
}
}
Expand Down Expand Up @@ -100,36 +113,28 @@ impl Pagination {
let Props {
page,
total_pages,
ref on_switch_page,
} = *props;
route_to_page: to,
} = props.clone();

html! {
<>
<<<<<<< HEAD
<a class="pagination-previous"
disabled={page==1}
onclick={on_switch_page.reform(move |_| page - 1)}
>
{ "Previous" }
</a>
<a class="pagination-next"
disabled={page==total_pages}
onclick={on_switch_page.reform(move |_| page + 1)}
=======
<a href="javascript:void(0)" class="pagination-previous"
disabled=page==1
onclick=on_switch_page.reform(move |_| page - 1)
>
{ "Previous" }
</a>
<a href="javascript:void(0)" class="pagination-next"
disabled=page==total_pages
onclick=on_switch_page.reform(move |_| page + 1)
>>>>>>> fbcb13a6 (Fix the examples.)
>
{ "Next page" }
</a>
</>
}
<>
<Link<Route, PageQuery>
classes={classes!("pagination-previous")}
disabled={page==1}
query={Some(PageQuery{page: page - 1})}
to={to.clone()}
>
{ "Previous" }
</Link<Route, PageQuery>>
<Link<Route, PageQuery>
classes={classes!("pagination-next")}
disabled={page==total_pages}
query={Some(PageQuery{page: page + 1})}
{to}
>
{ "Next page" }
</Link<Route, PageQuery>>
</>
}
}
}
8 changes: 4 additions & 4 deletions examples/router/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ impl Model {
{ "More" }
</a>
<div class="navbar-dropdown">
<Link<Route> classes={classes!("navbar-item")} route={Route::Authors}>
<Link<Route> classes={classes!("navbar-item")} to={Route::Authors}>
{ "Meet the authors" }
</Link<Route>>
</div>
Expand All @@ -124,15 +124,15 @@ impl Model {
}

fn switch(routes: &Route) -> Html {
match routes {
match routes.clone() {
Route::Post { id } => {
html! { <Post seed={*id} /> }
html! { <Post seed={id} /> }
}
Route::Posts => {
html! { <PostList /> }
}
Route::Author { id } => {
html! { <Author seed={*id} /> }
html! { <Author seed={id} /> }
}
Route::Authors => {
html! { <AuthorList /> }
Expand Down
2 changes: 1 addition & 1 deletion examples/router/src/pages/post.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl Component for Post {
html! {
<>
<section class="hero is-medium is-light has-background">
<img alt="The hero's background" class="hero-background is-transparent" src={Cow::Owned(post.meta.image_url.clone())} />
<img alt="The hero's background" class="hero-background is-transparent" src={post.meta.image_url.clone()} />
<div class="hero-body">
<div class="container">
<h1 class="title">
Expand Down
53 changes: 28 additions & 25 deletions examples/router/src/pages/post_list.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,55 @@
use crate::components::pagination::PageQuery;
use crate::components::{pagination::Pagination, post_card::PostCard};
use crate::Route;
use serde::{Deserialize, Serialize};
use yew::prelude::*;
use yew_router::prelude::*;

const ITEMS_PER_PAGE: u64 = 10;
const TOTAL_PAGES: u64 = u64::MAX / ITEMS_PER_PAGE;

#[derive(Clone, PartialEq, Properties)]
pub struct Props {}

pub enum Msg {
ShowPage(u64),
PageUpdated,
}

#[derive(Serialize, Deserialize)]
struct PageQuery {
pub struct PostList {
page: u64,
_listener: HistoryListener,
}

pub struct PostList;
fn current_page(ctx: &Context<PostList>) -> u64 {
let location = ctx.link().location().unwrap();

location.query::<PageQuery>().map(|it| it.page).unwrap_or(1)
}

impl Component for PostList {
type Message = Msg;
type Properties = ();

fn create(_ctx: &Context<Self>) -> Self {
Self
fn create(ctx: &Context<Self>) -> Self {
let link = ctx.link().clone();
let listener = ctx.link().history().unwrap().listen(move || {
link.send_message(Msg::PageUpdated);
});

Self {
page: current_page(ctx),
_listener: listener,
}
}

fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::ShowPage(page) => {
ctx.link()
.history()
.unwrap()
.push_with_query(Route::Posts, PageQuery { page })
.unwrap();
true
}
Msg::PageUpdated => self.page = current_page(ctx),
}
true
}

fn view(&self, ctx: &Context<Self>) -> Html {
let page = self.current_page(ctx);
let page = self.page;

html! {
<div class="section container">
Expand All @@ -50,15 +59,15 @@ impl Component for PostList {
<Pagination
{page}
total_pages={TOTAL_PAGES}
on_switch_page={ctx.link().callback(Msg::ShowPage)}
route_to_page={Route::Posts}
/>
</div>
}
}
}
impl PostList {
fn view_posts(&self, ctx: &Context<Self>) -> Html {
let start_seed = (self.current_page(ctx) - 1) * ITEMS_PER_PAGE;
fn view_posts(&self, _ctx: &Context<Self>) -> Html {
let start_seed = (self.page - 1) * ITEMS_PER_PAGE;
let mut cards = (0..ITEMS_PER_PAGE).map(|seed_offset| {
html! {
<li class="list-item mb-5">
Expand All @@ -81,10 +90,4 @@ impl PostList {
</div>
}
}

fn current_page(&self, ctx: &Context<Self>) -> u64 {
let location = ctx.link().location().unwrap();

location.query::<PageQuery>().map(|it| it.page).unwrap_or(1)
}
}
4 changes: 2 additions & 2 deletions packages/yew-macro/src/html_tree/lint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ where
match tree {
HtmlTree::List(list) => {
for child in &list.children.0 {
lint::<L>(&child)
lint::<L>(child)
}
}
HtmlTree::Element(el) => L::lint(&el),
HtmlTree::Element(el) => L::lint(el),
_ => {}
}
}
Expand Down
75 changes: 58 additions & 17 deletions packages/yew-router/src/components/link.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::marker::PhantomData;

use serde::Serialize;
use wasm_bindgen::UnwrapThrowExt;
use yew::prelude::*;

Expand All @@ -9,54 +10,94 @@ use crate::Routable;

/// Props for [`Link`]
#[derive(Properties, Clone, PartialEq)]
pub struct LinkProps<R: Routable> {
pub struct LinkProps<R, Q = ()>
where
R: Routable,
Q: Clone + PartialEq + Serialize,
{
/// CSS classes to add to the anchor element (optional).
#[prop_or_default]
pub classes: Classes,
/// Route that will be pushed when the anchor is clicked.
pub to: R,
/// Route query data
#[prop_or_default]
pub query: Option<Q>,
#[prop_or_default]
pub disabled: bool,
#[prop_or_default]
pub children: Children,
}

/// A wrapper around `<a>` tag to be used with [`Router`](crate::Router)
pub struct Link<R: Routable + 'static> {
_data: PhantomData<R>,
pub struct Link<R, Q = ()>
where
R: Routable + 'static,
Q: Clone + PartialEq + Serialize + 'static,
{
_route: PhantomData<R>,
_query: PhantomData<Q>,
}

pub enum Msg {
OnClick,
}

impl<R: Routable + 'static> Component for Link<R> {
impl<R, Q> Component for Link<R, Q>
where
R: Routable + 'static,
Q: Clone + PartialEq + Serialize + 'static,
{
type Message = Msg;
type Properties = LinkProps<R>;
type Properties = LinkProps<R, Q>;

fn create(_ctx: &Context<Self>) -> Self {
Self { _data: PhantomData }
Self {
_route: PhantomData,
_query: PhantomData,
}
}

fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::OnClick => {
ctx.link()
.history()
.expect_throw("failed to read history")
.push(ctx.props().to.clone());
let LinkProps { to, query, .. } = ctx.props();
let history = ctx.link().history().expect_throw("failed to read history");
match query {
None => {
web_sys::console::log_1(&"🚀 pushing no".into());
history.push(to.clone());
}
Some(data) => {
history
.push_with_query(to.clone(), data.clone())
.expect_throw("failed push history with query");
}
};
false
}
}
}

fn view(&self, ctx: &Context<Self>) -> Html {
let LinkProps {
classes,
to,
children,
disabled,
..
} = ctx.props().clone();
let onclick = ctx.link().callback(|e: MouseEvent| {
e.prevent_default();
Msg::OnClick
});
html! {
<a class={ctx.props().classes.clone()}
href={ctx.props().to.to_path()}
onclick={ctx.link().callback(|e: MouseEvent| {
e.prevent_default();
Msg::OnClick
})}
<a class={classes}
href={to.to_path()}
{onclick}
{disabled}
>
{ ctx.props().children.clone() }
{ children }
</a>
}
}
Expand Down

0 comments on commit 8c41db3

Please sign in to comment.