Skip to content

Commit c900fbd

Browse files
committed
fix: navbar Tutorial link now respects current locale and version
1 parent bc7a367 commit c900fbd

3 files changed

Lines changed: 100 additions & 27 deletions

File tree

tools/website-e2e/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ pub async fn assert_nav_button(client: &fantoccini::Client, text: &str) {
8686
find_nav_button(client, text).await;
8787
}
8888

89+
pub async fn click_nav_link(client: &fantoccini::Client, text: &str) {
90+
let xpath = format!("//nav//a[normalize-space(text())='{text}']");
91+
let link = client
92+
.find(Locator::XPath(&xpath))
93+
.await
94+
.unwrap_or_else(|_| panic!("nav link '{text}' not found"));
95+
link.click().await.unwrap();
96+
tokio::time::sleep(Duration::from_millis(800)).await;
97+
}
98+
8999
pub fn page_looks_japanese(text: &str) -> bool {
90100
let kana_count = text
91101
.chars()

tools/website-e2e/tests/navigation.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use std::time::Duration;
22

33
use fantoccini::Locator;
44
use website_e2e::{
5-
assert_nav_button as assert_version_selector, assert_path, build_dir, make_client,
6-
page_looks_chinese, page_looks_japanese, start_file_server,
5+
assert_nav_button as assert_version_selector, assert_path, build_dir, click_nav_link,
6+
make_client, page_looks_chinese, page_looks_japanese, start_file_server,
77
};
88

99
async fn assert_lang_selector(client: &fantoccini::Client, expected: &str) {
@@ -1501,3 +1501,29 @@ async fn dropdowns_close_on_outside_click() {
15011501

15021502
client.close().await.unwrap();
15031503
}
1504+
1505+
#[tokio::test]
1506+
async fn nav_tutorial_link_version_and_locale_aware() {
1507+
let addr = start_file_server(&build_dir()).await;
1508+
let base = format!("http://{addr}");
1509+
let client = make_client().await;
1510+
1511+
let cases: &[(&str, &str)] = &[
1512+
("/0.22/", "/0.22/tutorial"),
1513+
("/ja/0.21/", "/ja/0.21/tutorial"),
1514+
("/ja/docs/getting-started/editor-setup", "/ja/tutorial"),
1515+
];
1516+
1517+
for &(start, expected) in cases {
1518+
client.goto(&format!("{base}{start}")).await.unwrap();
1519+
tokio::time::sleep(Duration::from_millis(500)).await;
1520+
1521+
click_nav_link(&client, "Tutorial").await;
1522+
tokio::time::sleep(Duration::from_millis(500)).await;
1523+
1524+
let url = client.current_url().await.unwrap();
1525+
assert_path(&url, expected);
1526+
}
1527+
1528+
client.close().await.unwrap();
1529+
}

yew-rs/lib/src/components/navbar.rs

Lines changed: 62 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -245,21 +245,26 @@ pub fn Navbar(
245245
}
246246
</div>
247247
for (label, href, _) in nav_items {
248-
<a class={{
249-
let color = if *label == active_nav_label { "var(--color-primary)" } else { "var(--color-text)" };
250-
css!(
251-
color: ${color};
252-
text-decoration: none;
253-
padding: 0.5rem 0.75rem;
254-
font-size: 0.875rem;
255-
font-weight: 500;
256-
display: inline-flex;
257-
align-items: center;
258-
gap: 0.25rem;
259-
&:hover { color: var(--color-primary); text-decoration: none; }
260-
@media (max-width: 700px) { display: none; }
261-
)
262-
}} href={*href} onclick={crate::nav_onclick(&nav_ctx, href)}>{label}</a>
248+
{
249+
{
250+
let url = compute_nav_href(href, lang.as_str(), doc_version.as_str());
251+
let color = if *label == active_nav_label { "var(--color-primary)" } else { "var(--color-text)" };
252+
html! {
253+
<a class={css!(
254+
color: ${color};
255+
text-decoration: none;
256+
padding: 0.5rem 0.75rem;
257+
font-size: 0.875rem;
258+
font-weight: 500;
259+
display: inline-flex;
260+
align-items: center;
261+
gap: 0.25rem;
262+
&:hover { color: var(--color-primary); text-decoration: none; }
263+
@media (max-width: 700px) { display: none; }
264+
)} href={url.clone()} onclick={crate::nav_onclick(&nav_ctx, &url)}>{label}</a>
265+
}
266+
}
267+
}
263268
}
264269
<a class={css!(
265270
color: var(--color-text);
@@ -416,16 +421,23 @@ pub fn Navbar(
416421
-webkit-overflow-scrolling: touch;
417422
)}>
418423
for (label, href, _) in nav_items {
419-
<a class={css!(
420-
color: var(--color-text);
421-
text-decoration: none;
422-
padding: 0.75rem 0;
423-
font-size: 0.875rem;
424-
font-weight: 500;
425-
display: inline-flex;
426-
align-items: center;
427-
&:hover { color: var(--color-primary); text-decoration: none; }
428-
)} href={*href} onclick={crate::nav_onclick(&nav_ctx, href)}>{label}</a>
424+
{
425+
{
426+
let url = compute_nav_href(href, lang.as_str(), doc_version.as_str());
427+
html! {
428+
<a class={css!(
429+
color: var(--color-text);
430+
text-decoration: none;
431+
padding: 0.75rem 0;
432+
font-size: 0.875rem;
433+
font-weight: 500;
434+
display: inline-flex;
435+
align-items: center;
436+
&:hover { color: var(--color-primary); text-decoration: none; }
437+
)} href={url.clone()} onclick={crate::nav_onclick(&nav_ctx, &url)}>{label}</a>
438+
}
439+
}
440+
}
429441
}
430442
<a class={css!(
431443
color: var(--color-text);
@@ -561,6 +573,31 @@ fn DropdownItem(href: AttrValue, active: bool, children: Html) {
561573
}
562574
}
563575

576+
fn compute_nav_href(base_href: &str, lang: &str, doc_version: &str) -> String {
577+
let prefix = crate::lang_prefix(lang);
578+
let version_slug = VERSION_SLUGS
579+
.iter()
580+
.find(|(label, _)| *label == doc_version)
581+
.map(|(_, slug)| *slug)
582+
.unwrap_or("");
583+
584+
if base_href.starts_with("/tutorial") {
585+
if version_slug.is_empty() {
586+
return format!("{prefix}/tutorial");
587+
}
588+
return format!("{prefix}/{version_slug}/tutorial");
589+
}
590+
591+
if let Some(doc_path) = base_href.strip_prefix("/docs/") {
592+
if version_slug.is_empty() {
593+
return format!("{prefix}/docs/{doc_path}");
594+
}
595+
return format!("{prefix}/docs/{version_slug}/{doc_path}");
596+
}
597+
598+
format!("{prefix}{base_href}")
599+
}
600+
564601
fn compute_version_url(
565602
current_path: &str,
566603
current_lang: &str,

0 commit comments

Comments
 (0)