Skip to content

Commit

Permalink
Add dropdown to switch between Flutter-related sites (#11659)
Browse files Browse the repository at this point in the history
Adds a dropdown to the Flutter wordmark in the navbar, as well as a
badge to distinguish the docs site from the marketing site.

<img width="240" alt="Flutter site switcher expanded in light mode"
src="https://github.com/user-attachments/assets/4393530e-2e48-4354-9358-8ccc2ec147da"
/>

---
Resolves #11658
  • Loading branch information
parlough authored Feb 3, 2025
1 parent 35bda67 commit 0fae876
Show file tree
Hide file tree
Showing 6 changed files with 256 additions and 22 deletions.
67 changes: 50 additions & 17 deletions src/_includes/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,47 @@
Skip to main content
</a>
<nav class="navbar">
<button
id="menu-toggle"
class="icon-button"
type="button"
aria-controls="sidenav"
aria-label="Toggle navigation"
title="Toggle navigation">
<span class="material-symbols" aria-hidden="true">menu</span>
</button>

<a class="navbar-brand" href="/">
<img
src='/assets/images/branding/flutter/logo+text/horizontal/default.svg'
alt='Flutter logo'
height="37"
width="129">
</a>
<div id="site-switcher" class="dropdown">
<button class="dropdown-button site-wordmark" aria-expanded="false" aria-controls="site-switcher-menu" aria-label="Switch between Flutter and Dart sites">
<img src="/assets/images/branding/flutter/logo/default.svg" alt="Flutter logo" width="28">
<span>Flutter</span>
<span class="subtype">Docs</span>
<span class="material-symbols" aria-hidden="true">unfold_more</span>
</button>
<div class="dropdown-content" id="site-switcher-menu">
<nav class="dropdown-menu" role="menu">
<ul>
<li role="presentation"><a href="{{site.main-url}}" class="site-wordmark" role="menuitem" title="Flutter homepage" aria-label="Go to the Flutter homepage">
<img src="/assets/images/branding/flutter/logo/default.svg" alt="Flutter logo" width="28">
<span>Flutter</span>
</a></li>
<li role="presentation"><a href="{{site.url}}" class="site-wordmark current-site" role="menuitem" aria-current="true" title="Flutter docs homepage" aria-label="Go to the Flutter docs homepage">
<img src="/assets/images/branding/flutter/logo/default.svg" alt="Flutter logo" width="28">
<span>Flutter</span>
<span class="subtype">Docs</span>
</a></li>
<li role="presentation"><a href="{{site.api}}" class="site-wordmark" role="menuitem" title="Flutter API reference" aria-label="Go to the Flutter API reference">
<img src="/assets/images/branding/flutter/logo/default.svg" alt="Flutter logo" width="28">
<span>Flutter</span>
<span class="subtype">API</span>
</a></li>
<li aria-hidden="true" class="dropdown-divider" role="separator"></li>
<li role="presentation"><a href="{{site.dart-site}}" class="site-wordmark" role="menuitem" title="Dart homepage" aria-label="Go to the Dart homepage">
<img src="/assets/images/branding/dart/logo.svg" alt="Dart logo" width="28" height="28">
<span>Dart</span>
</a></li>
<li role="presentation"><a href="{{site.dartpad}}" class="site-wordmark" role="menuitem" title="DartPad playground" aria-label="Go to the DartPad playground">
<img src="/assets/images/branding/dart/logo.svg" alt="Dart logo" width="28" height="28">
<span>DartPad</span>
</a></li>
<li role="presentation"><a href="{{site.pub}}" class="site-wordmark" role="menuitem" title="pub.dev homepage" aria-label="Go to the pub.dev homepage">
<img src="/assets/images/branding/dart/logo.svg" alt="Dart logo" width="28" height="28">
<span>pub.dev</span>
</a></li>
</ul>
</nav>
</div>
</div>

<div class="navbar-contents">
<ul class="navbar-nav">
Expand All @@ -48,6 +72,15 @@
<span class="material-symbols" aria-hidden="true">search</span>
</a>
<a id="call-to-action" class="filled-button" href="/get-started/install/">Get started</a>
<button
id="menu-toggle"
class="icon-button"
type="button"
aria-controls="sidenav"
aria-label="Toggle navigation"
title="Toggle navigation">
<span class="material-symbols" aria-hidden="true">menu</span>
</button>
</div>
</nav>
</header>
6 changes: 3 additions & 3 deletions src/_sass/components/_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
padding: .5rem 1rem;
padding: 0.5rem 0.75rem;

min-height: $site-header-height;

#menu-toggle {
margin-right: 0.75rem;
margin-left: 0.25rem;

@media (min-width: 1024px) {
display: none;
Expand Down Expand Up @@ -72,7 +72,7 @@
padding: 0.5rem 1rem !important;
display: none;

@media (min-width: 768px) {
@media (min-width: 1024px) {
display: unset;
}
}
Expand Down
123 changes: 123 additions & 0 deletions src/_sass/components/_site-switcher.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
@use '../base/mixins';
@use '../base/variables' as *;

.dropdown {
position: relative;
display: inline-flex;
justify-content: center;
}

button.dropdown-button {
padding: 0.4rem 0.6rem;
border-radius: 0.25rem;

.material-symbols:last-child {
margin-left: 0.4rem;
color: rgba(85, 85, 85, 0.6);
font-size: 1rem;
width: 0.7rem;
}

&:hover {
.material-symbols {
color: rgba(85, 85, 85, 0.8);
}
}
}

.dropdown-content {
display: none;
position: absolute;
background-color: var(--site-switcher-bg, #ffffff);
box-shadow: 0 6px 18px 0 rgba(0, 0, 0, 0.2);
z-index: 1060;
border-radius: 0.4rem;
width: max-content;
top: 2.25rem;
transform: scale(0.9);

&.show {
display: block;
}

.dropdown-menu {
padding: 0.4rem;

ul {
display: flex;
flex-direction: column;
list-style: none;
padding: 0;
margin: 0;

li {
padding: 0.3rem;

a {
display: flex;
align-items: center;
flex-direction: row;

text-decoration: none;
}
}
}

.dropdown-divider {
background-color: #e7e8ed;
border-radius: 0.5rem;
height: 0.125rem;
margin: 0.25rem;
padding: 0;
}
}
}

.site-wordmark {
padding: 0.4rem 0.6rem;
border-radius: 0.25rem;
align-items: center;
display: flex;
flex-direction: row;
cursor: pointer;

font-variant-ligatures: none;
font-size: 1.75rem;
line-height: 1.25em;
letter-spacing: 0.015em;
font-family: 'Google Sans', sans-serif;
user-select: none;

> img {
width: 28px;
margin-right: 0.75rem;
}

&.current-site {
background-color: rgba(194, 229, 255, 0.4);
}

&:hover {
@include mixins.interaction-style(4%);
}

&:active {
@include mixins.interaction-style(6%);
}

span {
color: #4a4a4a;
}

span.subtype {
padding: 0 0.3rem;
font-size: 1.25rem;
font-weight: 500;
color: $site-color-body;
line-height: 1.3;
border-radius: 0.25rem;
background-color: rgb(194, 229, 255);
margin-left: 0.4rem;
letter-spacing: normal;
}
}
1 change: 1 addition & 0 deletions src/_sass/site.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
@use 'components/next-prev-nav';
@use 'components/pill';
@use 'components/sidebar';
@use 'components/site-switcher';
@use 'components/tabs';
@use 'components/toc';

Expand Down
26 changes: 26 additions & 0 deletions src/content/assets/images/branding/dart/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
55 changes: 53 additions & 2 deletions src/content/assets/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,15 +253,66 @@ function setUpCodeBlockButtons() {
});
}

function setupSiteSwitcher() {
const siteSwitcher = document.getElementById('site-switcher');

if (!siteSwitcher) {
return;
}

const siteSwitcherButton = siteSwitcher.querySelector('.dropdown-button');
const siteSwitcherMenu = siteSwitcher.querySelector('#site-switcher-menu');
if (!siteSwitcherButton || !siteSwitcherMenu) {
return;
}

function _closeMenusAndToggle() {
siteSwitcherMenu.classList.remove('show');
siteSwitcherButton.ariaExpanded = 'false';
}

siteSwitcherButton.addEventListener('click', (_) => {
if (siteSwitcherMenu.classList.contains('show')) {
_closeMenusAndToggle();
} else {
siteSwitcherMenu.classList.add('show');
siteSwitcherButton.ariaExpanded = 'true';
}
});

document.addEventListener('keydown', (event) => {
// If pressing the `esc` key in the menu area, close the menu.
if (event.key === 'Escape' && event.target.closest('#site-switcher')) {
_closeMenusAndToggle();
}
});

siteSwitcher.addEventListener('focusout', (e) => {
// If focus leaves the site-switcher, hide the menu.
if (e.relatedTarget && !e.relatedTarget.closest('#site-switcher')) {
_closeMenusAndToggle();
}
});

document.addEventListener('click', (event) => {
// If not clicking inside the site switcher, close the menu.
if (!event.target.closest('#site-switcher')) {
_closeMenusAndToggle();
}
});
}

document.addEventListener("DOMContentLoaded", function(_) {
adjustToc();
setupInlineToc();
scrollSidenavIntoView();
initCookieNotice();

setupSidenavInteractivity();
setUpCodeBlockButtons();

setupSearch();
setupSiteSwitcher();
setupTabs();

adjustToc();
setupInlineToc();
});

0 comments on commit 0fae876

Please sign in to comment.