* 9087 - New Navigation

* 9087 - New Navigation

* Include mobile search functionality and feedback

* Fix tests

* Fixed donate button
This commit is contained in:
Simon Fessehaye 2022-09-01 15:28:30 -07:00 коммит произвёл GitHub
Родитель 2e94c411d4
Коммит c3ed04434e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
20 изменённых файлов: 363 добавлений и 218 удалений

Просмотреть файл

@ -1,12 +1,17 @@
{% load bg_nav_tags i18n localization wagtailcore_tags %}
{% load bg_nav_tags i18n localization wagtailcore_tags static %}
{% get_bg_home_page as home_page %}
{{ pre }}
{% with home_page.get_editorial_content_index as editorial_content_index %}
<a class="{{ class }} product-review-link" href="{% relocalized_url home_page.url %}#product-review">{% trans "Product Reviews" %}</a>
<img
class="tw-mr-4 tw-hidden large:tw-block {{ class }}"
src="{% static "_images/buyers-guide/asterick-mini.svg" %}"
>
{% if editorial_content_index %}
<a class="{{ class }} {% bg_active_nav request.get_full_path editorial_content_index.url %} " href="{% pageurl editorial_content_index %}">{{ editorial_content_index }}</a>
{% endif %}
{% endwith %}
{% localizedroutablepageurl home_page 'about-why-view' as about_why_url %}
<a class="{{ class }} {% bg_active_nav request.get_full_path about_why_url %}" href="{{ about_why_url }}">{% trans "About the Guide" %}</a>
<a class="{{ class }} {% bg_active_nav request.get_full_path about_why_url %}" href="{{ about_why_url }}">{% trans "About" %}</a>
{{ post }}

Просмотреть файл

@ -1,30 +1,63 @@
{% extends "partials/primary_nav.html" %}
{% load bg_nav_tags i18n localization %}
{% load bg_nav_tags i18n localization static %}
{% block mobile-search %}
<div id="pni-mobile-container" class="tw-hidden large:tw-hidden tw-absolute tw-mt-[64px] small:tw-mt-[69px] medium:tw-mt-[78px] tw-top-0 tw-w-full tw-left-0 tw-bg-blue-05">
<div class="tw-container">
<div class="tw-row">
<div class="tw-px-4 tw-flex tw-items-center tw-w-full">
<img
class="tw-w-4 tw-h-4 tw-mr-2"
src="{% static "_images/buyers-guide/pni-search.svg" %}"
>
<input
id="pni-mobile-bar"
type="text"
class="tw-w-full tw-bg-blue-05 tw-outline-none tw-py-4 tw-text-base tw-text-blue-60"
placeholder="{% trans "Search All Products" %}"
>
<label for="pni-mobile-bar" class="clear-icon">&nbsp;</label>
</div>
</div>
</div>
</div>
{% endblock %}
{% block nav_logo %}
{% get_bg_home_page as home_page %}
<div class="d-flex align-items-center logo-section">
<a href="/" class="moz-logo mb-0 mr-3"><span class="sr-only">Mozilla</span></a>
<p class="mb-0 tw-h3-heading flex-wrap">
<a class="link-back" href="{% relocalized_url home_page.url %}">{% trans "*Privacy Not Included" context 'Buyers guide name. This can be localized. This is a reference to the “*batteries not included” mention on toys.' %}</a>
{% get_bg_home_page as home_page %}
<div class="tw-flex tw-flex-col logo-section tw-mx-auto large:tw-mx-0">
<p class="mb-0 tw-h3-heading tw-max-w-none flex-wrap">
<a class="link-back tw-flex" href="{% relocalized_url home_page.url %}">
<img
class="tw-mr-1 tw-w-3 tw-h-3 large:tw-w-4 large:tw-h-4"
src="{% static "_images/buyers-guide/asterick-mini.svg" %}"
>
<span class="tw-font-semibold tw-text-base tw-leading-4 large:tw-text-[32px] large:tw-leading-[28px]">{% trans "Privacy Not Included" context 'Buyers guide name. This can be localized. This is a reference to the “*batteries not included” mention on toys.' %}</span>
</a>
</p>
<a href="/" class="moz-logo mb-0 mr-3 large:tw-mt-2 tw-ml-4 large:tw-ml-[20px]"><span class="sr-only">Mozilla</span></a>
</div>
{% endblock %}
{% block narrow_screen_nav_links %}
{% get_bg_home_page as home_page %}
<div><a class="{% bg_active_nav request.get_full_path home_page.url %}" href="{% relocalized_url home_page.url %}">{% trans "Privacy Not Included" %}</a></div>
{% include "fragments/buyersguide/pni_nav_links.html" with pre="<div>" post="</div>" %}
{% get_bg_home_page as home_page %}
{% include "fragments/buyersguide/pni_nav_links.html" with class="tw-block tw-w-fit" pre="<div>" post="</div>" %}
{% endblock %}
{% block wide_screen_menu %}{% endblock %}
{% block wide_screen_menu %}
{% endblock %}
{% block donate_and_newsletter %}
<div class="d-flex align-items-center">
{% include "fragments/buyersguide/pni_nav_links.html" with class="primary-nav-special-link d-none d-md-block" %}
<a id="donate-header-btn" class="primary-nav-special-link tw-heart-glyph" href="https://donate.mozilla.org/?utm_source=foundation.mozilla.org&utm_medium=referral&utm_campaign=fmonav&utm_content=header" target="_blank" rel="noopener noreferrer">{% trans "Donate" %}</a>
{% include "fragments/buyersguide/pni_nav_links.html" with class="primary-nav-special-link pni-nav-link tw-hidden large:tw-block" %}
<a id="donate-header-btn" class="primary-nav-special-link pni-nav-link tw-hidden large:tw-block" href="https://donate.mozilla.org/?utm_source=foundation.mozilla.org&utm_medium=referral&utm_campaign=fmonav&utm_content=header" target="_blank" rel="noopener noreferrer">{% trans "Donate" %}</a>
{% if page.signup == None %}<button class="tw-btn-secondary btn-newsletter d-none d-lg-block ml-md-3">{% trans "Newsletter" %}</button>{% endif %}
<button class="tw-bg-transparent" id="mobile-search">
<img
class="large:tw-hidden tw-w-5 tw-h-5"
src="{% static "_images/buyers-guide/pni-search.svg" %}"
>
</button>
</div>
{% endblock %}

Просмотреть файл

@ -83,8 +83,8 @@
{% block category_nav %}
{% get_bg_home_page as home_page %}
{% include "fragments/buyersguide/pni_mobile_nav.html" with pagetype=pagetype categories=categories current_category=current_category %}
<nav id="multipage-nav" class="pni-category-nav text-center d-none d-md-block" title="{% trans "site navigation" context "Tooltip on menu items" %}">
<div class="container">
<nav id="multipage-nav" class="pni-category-nav text-center d-none d-md-block tw-no-scrollbar tw-mt-2" title="{% trans "site navigation" context "Tooltip on menu items" %}">
<div class="container" id="product-review">
<div class="row">
<div class="col">
{% if pagetype == "product" or pagetype == "about" %}
@ -103,6 +103,16 @@
{% endif %}
{% endwith %}
{% endfor %}
<div id="product-filter-search" tabindex="0" class="tw-hidden large:tw-inline-flex tw-px-2 tw-items-center tw-bg-blue-05 tw-border-4 tw-border-blue-05 tw-w-[214px] tw-mr-4">
<img
class="tw-w-4 tw-h-4 tw-mr-2"
src="{% static "_images/buyers-guide/pni-search.svg" %}"
>
<input type="text" role="searchbox" id="product-filter-search-input" placeholder="{% trans "Search all products" %}" value=""
class="tw-bg-blue-05 tw-outline-none tw-py-2 tw-text-base tw-text-blue-60 tw-min-w-0" />
<label for="product-filter-search-input" class="clear-icon">&nbsp;</label>
</div>
</div>
</div>
</div>

Просмотреть файл

@ -10,28 +10,6 @@
<input type="hidden" class="category-title" value="{% if current_category %}{{current_category.localized.name}}{% else %}None{% endif %}">
<input type="hidden" class="parent-title" value="{{current_category.parent.localized.name}}">
<header
class="container-fluid text-center page-header tw-bg-gray-05"
role="banner"
>
<h1 class="tw-sr-only">{{ page.title }}</h1>
<!-- home banner as css background -->
<div class="container">
<div class="row">
<div class="col-12 col-lg-8 offset-lg-2 intro-text order-2 order-lg-1">
<p class="tw-body-large mb-0">{{ page.intro_text }}</p>
<div id="product-filter-search" class='col-12 col-md-9 tw-my-5' tabindex="0">
<span class="search-icon">&nbsp;</span>
<input type="text" role="searchbox" id="product-filter-search-input" placeholder="{% trans "Search all products" %}" class="tw-body-large tw-text-black" value="">
<label for="product-filter-search-input" class="clear-icon">&nbsp;</label>
</div>
</div>
<div class="col-12 col-lg-2 badge-container text-right order-1 order-lg-2">
<img class="webby-award-badge" src="{% static '_images/buyers-guide/webby-award-badge.svg' %}" alt="{% trans "2020 Webby Award Winner Badge" %}">
</div>
</div>
</div>
</header>
{% endblock %}
{% block guts %}

Просмотреть файл

@ -5,25 +5,29 @@
{% block hero %}
{{ block.super }}
<div class="editorial-content">
{% with hero_featured_article=page.hero_featured_article %}
{% if hero_featured_article %}
<div>
<h2 class="tw-h1-heading">
<a href=" {% pageurl hero_featured_article %}">{{ hero_featured_article.title }}</a>
</h2>
<div class="tw-container">
<div class="tw-row">
<div class="tw-px-4 tw-w-full">
<h2 class="tw-h1-heading">
<a href=" {% pageurl hero_featured_article %}">{{ hero_featured_article.title }}</a>
</h2>
<div>
By
{% with author_profiles=hero_featured_article.author_profile_relations.related_items %}
{% if author_profiles %}
<ul>
{% for author_profile in author_profiles %}
<li>{{ author_profile.name }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<div>
By
{% with author_profiles=hero_featured_article.author_profile_relations.related_items %}
{% if author_profiles %}
<ul>
{% for author_profile in author_profiles %}
<li>{{ author_profile.name }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</div>
</div>
</div>
</div>
{% endif %}
@ -76,4 +80,5 @@
</div>
</div>
</div>
{% endblock hero %}

Просмотреть файл

@ -5,7 +5,8 @@
{% endif %}
<div class="wrapper-burger">
<div class="menu-container">
{% block mobile-search %}
{% endblock %}
<div class="narrow-screen-menu hidden d-lg-none">
{% block narrow_screen_menu %}
<div class="narrow-screen-menu-background tw-dark">
@ -32,7 +33,7 @@
<div class="row">
<div class="col">
<div class="d-flex flex-row justify-content-between">
<div id="primary-nav-links">
<div id="primary-nav-links" class="tw-w-full large:tw-w-auto">
<div class="d-flex align-items-center flex-wrap">
<button class="burger {% if page.zen_nav is not True %} d-lg-none ml-md-0 {% endif %}" aria-label="{% trans 'Open menu' %}">
@ -63,7 +64,7 @@
{% block donate_and_newsletter %}
<div class="d-flex align-items-center">
<a id="donate-header-btn" class="primary-nav-special-link tw-heart-glyph" href="https://donate.mozilla.org/?utm_source=foundation.mozilla.org&utm_medium=referral&utm_campaign=fmonav&utm_content=header" target="_blank" rel="noopener noreferrer">{% trans "Donate" %}</a>
<a id="donate-header-btn" class="primary-nav-special-link tw-heart-glyph tw-flex" href="https://donate.mozilla.org/?utm_source=foundation.mozilla.org&utm_medium=referral&utm_campaign=fmonav&utm_content=header" target="_blank" rel="noopener noreferrer">{% trans "Donate" %}</a>
{% if page.signup == None %}<button class="tw-btn-secondary btn-newsletter d-none d-lg-block ml-md-3">{% trans "Newsletter" %}</button>{% endif %}
</div>
{% endblock %}

Просмотреть файл

@ -0,0 +1,3 @@
<svg width="11" height="10" viewBox="0 0 11 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.5556 3.46041L7.41261 5.01466L10.5556 6.56892L9.13234 8.76833L6.37484 6.92082L6.5824 10H3.94351L4.15106 6.95015L1.42322 8.76833L0 6.56892L3.1133 5.01466L0 3.46041L1.39357 1.261L4.18071 3.13783L3.94351 0H6.5824L6.34519 3.16715L9.16199 1.261L10.5556 3.46041Z" fill="#595CF3"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 390 B

Просмотреть файл

@ -0,0 +1,4 @@
<svg width="19" height="19" viewBox="0 0 19 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="7.20361" cy="7.75" r="6" stroke="#3032D9" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M17.3286 17.875L11.567 12.1134" stroke="#3032D9" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 347 B

Просмотреть файл

@ -8,11 +8,6 @@ function getQuerySelectorEvents(pageTitle, productName) {
action: `donate tap`,
label: `${pageTitle} donate header`,
},
".donate-banner a.tw-btn-secondary": {
category: `buyersguide`,
action: `donate tap`,
label: `${pageTitle} donate footer`,
},
// product events
"#product-company-url": {

Просмотреть файл

@ -1,12 +1,13 @@
.moz-logo {
background-image: url("../_images/mozilla-m.svg");
background-image: url("../_images/mozilla-on-black.svg");
background-repeat: no-repeat;
flex-shrink: 0;
width: 28px;
height: 28px;
width: 40px;
height: 12px;
@media (min-width: $nav-full-logo-breakpoint) {
width: 97px;
background-image: url("../_images/mozilla-on-black.svg");
@media (min-width: $bp-lg) {
width: 62px;
height: 18px;
}
}
@ -25,17 +26,6 @@
}
.logo-section {
.tw-h3-heading {
font-size: 13px;
font-weight: 600;
max-width: 85px;
@media (min-width: $pni-primary-nav-breakpoint) {
font-size: 22px;
max-width: none;
}
}
a.link-back {
color: inherit;
text-decoration: none;
@ -45,3 +35,8 @@
#nav-newsletter-form-wrapper.expanded {
z-index: 11; /* this element needs to overlay header.scss's ".category-nav", which has z-index: 10 */
}
.narrow-screen-menu-container .nav-links {
width: 140px;
margin: 0 auto;
}

Просмотреть файл

@ -12,9 +12,27 @@ const toggle = document.querySelector(`#product-filter-pni-toggle`);
* @param {*} searchBar
* @param {*} searchInput
*/
export function setupHistoryManagement(instance, searchBar, searchInput) {
setupPopStateHandler(instance, searchBar, searchInput);
performInitialHistoryReplace(instance, searchBar, searchInput);
export function setupHistoryManagement(
instance,
searchBar,
searchInput,
mobileSearchBar,
mobileSearchInput
) {
setupPopStateHandler(
instance,
searchBar,
searchInput,
mobileSearchBar,
mobileSearchInput
);
performInitialHistoryReplace(
instance,
searchBar,
searchInput,
mobileSearchBar,
mobileSearchInput
);
}
/**
@ -23,7 +41,13 @@ export function setupHistoryManagement(instance, searchBar, searchInput) {
* @param {*} searchBar
* @param {*} searchInput
*/
export function performInitialHistoryReplace(instance, searchBar, searchInput) {
export function performInitialHistoryReplace(
instance,
searchBar,
searchInput,
mobileSearchBar,
mobileSearchInput
) {
history.replaceState(
{
title: Utils.getTitle(categoryTitle.value.trim()),
@ -39,10 +63,36 @@ export function performInitialHistoryReplace(instance, searchBar, searchInput) {
if (history.state?.search) {
searchBar.classList.add(`has-content`);
searchInput.value = history.state?.search;
mobileSearchBar.classList.add(`has-content`);
mobileSearchInput.value = history.state?.search;
instance.filter(history.state?.search);
} else {
searchBar.classList.remove(`has-content`);
searchInput.value = ``;
mobileSearchBar.classList.remove(`has-content`);
mobileSearchInput.value = ``;
}
const url = new URLSearchParams(window.location.search);
const searchParameter = url.get("search");
if (searchParameter) {
history.replaceState(
{
title: Utils.getTitle(categoryTitle.value.trim()),
category: categoryTitle.value.trim(),
parent: parentTitle.value.trim(),
search: searchParameter ?? "",
filter: history.state?.filter,
},
Utils.getTitle(categoryTitle.value.trim()),
location.href
);
searchBar.classList.add(`has-content`);
searchInput.value = history.state?.search;
mobileSearchBar.classList.add(`has-content`);
mobileSearchInput.value = history.state?.search;
instance.filter(history.state?.search);
}
if (history.state?.filter) {
@ -73,7 +123,13 @@ export function performInitialHistoryReplace(instance, searchBar, searchInput) {
* @param {*} searchBar
* @param {*} searchInput
*/
export function setupPopStateHandler(instance, searchBar, searchInput) {
export function setupPopStateHandler(
instance,
searchBar,
searchInput,
mobileSearchBar,
mobileSearchInput
) {
window.addEventListener(`popstate`, (event) => {
const { state } = event;
if (!state) return; // if it's a "real" back, we shouldn't need to do anything
@ -87,7 +143,9 @@ export function setupPopStateHandler(instance, searchBar, searchInput) {
parentTitle.value = parent;
searchBar.classList.remove(`has-content`);
mobileSearchBar.classList.remove(`has-content`);
searchInput.value = ``;
mobileSearchInput.value = ``;
if (parent) {
Utils.highlightParentCategory();
@ -127,6 +185,8 @@ export function setupPopStateHandler(instance, searchBar, searchInput) {
instance.toggleSubcategory(true);
searchBar.classList.add(`has-content`);
searchInput.value = history.state?.search;
mobileSearchBar.classList.add(`has-content`);
mobileSearchInput.value = history.state?.search;
instance.filter(history.state?.search);
}

Просмотреть файл

@ -194,3 +194,30 @@ export function setupGoBackToAll(instance) {
parentTitle.value = "";
});
}
/**
* ...
* @param {*} instance
*/
export function setupReviewLinks(instance) {
const navLinks = document.querySelectorAll(`.product-review-link`);
if (!navLinks) return;
for (const nav of navLinks) {
nav.addEventListener("click", (evt) => {
const editorialContent = document.querySelector(".editorial-content");
const burger = document.querySelector(".burger");
if (editorialContent) {
evt.preventDefault();
evt.stopPropagation();
location.hash = "product-review";
editorialContent.classList.add("tw-hidden");
if (burger && burger.classList.contains("menu-open")) {
document.querySelector(".burger").click();
}
}
});
}
}

Просмотреть файл

@ -4,7 +4,11 @@ import { Utils } from "./utils.js";
import { CreepUtils } from "./creep-utils.js";
import { markScrollStart } from "./slider-area.js";
import { setupHistoryManagement, applyHistory } from "./history.js";
import { setupNavLinks, setupGoBackToAll } from "./member-functions.js";
import {
setupNavLinks,
setupGoBackToAll,
setupReviewLinks,
} from "./member-functions.js";
/**
* ...
*/
@ -18,10 +22,25 @@ export class SearchFilter {
this.allProducts = document.querySelectorAll(`figure.product-box`);
this.categoryTitle = document.querySelector(`.category-title`);
const { searchBar, searchInput } = this.setupSearchBar();
const { searchBar, searchInput, mobileSearchBar, mobileSearchInput } =
this.setupSearchBar();
setupNavLinks(this);
setupGoBackToAll(this);
setupHistoryManagement(this, searchBar, searchInput);
setupHistoryManagement(
this,
searchBar,
searchInput,
mobileSearchBar,
mobileSearchInput
);
setupReviewLinks(this);
if (location.hash && location.hash === "#product-review") {
const editorialContent = document.querySelector(".editorial-content");
if (editorialContent) {
editorialContent.classList.add("tw-hidden");
}
}
const subContainer = document.querySelector(`.subcategory-header`);
subContainer.addEventListener(`mousedown`, markScrollStart);
@ -59,7 +78,11 @@ export class SearchFilter {
`#product-filter-search`
));
if (!searchBar) {
const mobileSearchBar = (this.mobileSearchBar = document.querySelector(
`#pni-mobile-container`
));
if (!searchBar || !mobileSearchBar) {
return console.warn(
`Could not find the PNI search bar. Search will not be available.`
);
@ -75,11 +98,14 @@ export class SearchFilter {
const searchInput = (this.searchInput = searchBar.querySelector(`input`));
const mobileSearchInput = (this.mobileSearchInput =
mobileSearchBar.querySelector(`input`));
searchInput.addEventListener(
`input`,
debounce(() => {
const searchText = searchInput.value.trim();
mobileSearchInput.value = searchInput.value.trim();
if (searchText) {
searchBar.classList.add(`has-content`);
this.filter(searchText);
@ -90,8 +116,24 @@ export class SearchFilter {
}, 500)
);
mobileSearchInput.addEventListener(
`input`,
debounce(() => {
const searchText = mobileSearchInput.value.trim();
searchInput.value = mobileSearchInput.value.trim();
if (searchText) {
mobileSearchBar.classList.add(`has-content`);
this.filter(searchText);
} else {
this.clearText();
applyHistory(this);
}
}, 500)
);
const clear = searchBar.querySelector(`.clear-icon`);
if (!clear) {
const mobileClear = mobileSearchBar.querySelector(`.clear-icon`);
if (!clear || !mobileClear) {
return console.warn(
`Could not find the PNI search input clear icon. Search will work, but clearing will not.`
);
@ -104,16 +146,37 @@ export class SearchFilter {
applyHistory(this);
});
return { searchBar, searchInput };
mobileClear.addEventListener(`click`, (evt) => {
evt.preventDefault();
mobileSearchInput.focus();
this.clearText();
applyHistory(this);
});
return { searchBar, searchInput, mobileSearchBar, mobileSearchInput };
}
getURL(text) {
const url = new URL(location.href);
if (text) {
url.searchParams.set("search", text);
} else {
url.searchParams.delete("search");
}
url.search = url.searchParams.toString();
return url.toString();
}
/**
* Clear the search text
*/
clearText() {
const { searchBar, searchInput } = this;
const { searchBar, searchInput, mobileSearchBar, mobileSearchInput } = this;
searchBar.classList.remove(`has-content`);
mobileSearchBar.classList.remove(`has-content`);
searchInput.value = ``;
mobileSearchInput.value = ``;
gsap.set(this.allProducts, { opacity: 1, scale: 1 });
this.allProducts.forEach((product) => {
@ -126,7 +189,7 @@ export class SearchFilter {
const state = { ...history.state, search: "" };
const title = Utils.getTitle(this.categoryTitle.value.trim());
history.replaceState(state, title, location.href);
history.replaceState(state, title, this.getURL(""));
}
/**
@ -146,7 +209,7 @@ export class SearchFilter {
const state = { ...history.state, search: text };
const title = Utils.getTitle(this.categoryTitle.value.trim());
history.replaceState(state, title, location.href);
history.replaceState(state, title, this.getURL(text));
Utils.sortFilteredProducts();
CreepUtils.moveCreepyFace();

Просмотреть файл

@ -1,8 +1,10 @@
import mobileNavStickinessHandler from "./mobile-nav-stickiness-handler";
import mobileSearchBar from "./mobile-search-bar";
/**
* Bind event handlers
*/
export const bindEventHandlers = () => {
mobileNavStickinessHandler();
mobileSearchBar();
};

Просмотреть файл

@ -4,15 +4,15 @@
* Without making primary-nav.js more complicated just to handle this special case,
* we use MutationObserver to detect PNI's mobile menu's close/open state
* so we can toggle class on .primary-nav-container-wrapper to
* acheive the visual effects we want.
* achieve the visual effects we want.
*/
export default () => {
const menuBurger = document.querySelector(".burger");
const primanyNavContainer = document.querySelector(
const primaryNavContainer = document.querySelector(
".primary-nav-container-wrapper"
);
if (!menuBurger || !primanyNavContainer) return;
if (!menuBurger || !primaryNavContainer) return;
const classToDetect = "menu-open";
const classToToggle = "sticky-top";
@ -25,9 +25,12 @@ export default () => {
if (prevMenuState !== currentMenuState) {
prevMenuState = currentMenuState;
if (currentMenuState) {
primanyNavContainer.classList.add(classToToggle);
primaryNavContainer.classList.add(classToToggle);
document
.querySelector("#pni-mobile-container")
.classList.add("tw-hidden");
} else {
primanyNavContainer.classList.remove(classToToggle);
primaryNavContainer.classList.remove(classToToggle);
}
}
}

Просмотреть файл

@ -0,0 +1,59 @@
export default () => {
const mobileSearch = document.querySelector("#mobile-search");
const searchContainer = document.querySelector("#pni-mobile-container");
if (!mobileSearch) return;
mobileSearch.addEventListener("click", function () {
const burger = document.querySelector(".burger");
if (!searchContainer) return;
if (burger && burger.classList.contains("menu-open")) {
document.querySelector(".burger").click();
}
searchContainer.classList.toggle("tw-hidden");
});
/**
* if the user is not on the product review pages,
* the search bar has a different behavior that redirects to product review
*/
if (
!location.pathname.includes("categories") &&
!location.pathname.endsWith("/privacynotincluded/")
) {
const input = document.querySelector("#pni-mobile-bar");
const clearIcon = document.querySelector(
"#pni-mobile-container .clear-icon"
);
clearIcon.addEventListener("click", function () {
searchContainer.classList.remove(`has-content`);
input.value = "";
});
input.addEventListener(`input`, function () {
const searchText = input.value.trim();
if (searchText) {
searchContainer.classList.add(`has-content`);
} else {
searchContainer.classList.remove(`has-content`);
}
});
input.addEventListener("keypress", function (event) {
// If the user presses the "Enter" key on the keyboard or mobile
if (event.key === "Enter" && input.value) {
event.preventDefault();
const url = new URL("/privacynotincluded/", location.href);
url.searchParams.set("search", input.value);
url.search = url.searchParams.toString();
url.hash = "product-review";
location.href = url.toString();
}
});
}
};

Просмотреть файл

@ -8,6 +8,7 @@ $pni-purple-pink: #b0379b;
$pni-pink: #e4487d;
$pni-gradient: linear-gradient(to right, $pni-blue 0%, $pni-pink 100%);
$pni-warning-yellow: #fbd545;
$pni-wavy-blue: #595cf3;
$pni-product-list-background: #f5f5f5; /* keep this #f5f5f5 as this is the background colour product images on Homepage have */
$pni-product-image-background: #f4f4f4; /* keep this #f4f4f4 as this is the background colour product images on Product Page have */

Просмотреть файл

@ -23,8 +23,6 @@ body.pni #nav-newsletter-form-wrapper {
overflow-x: auto;
white-space: nowrap;
@include set-category-border-bottom-style();
a {
display: inline-block;
height: 42px;

Просмотреть файл

@ -1,4 +1,4 @@
body.catalog {
body {
$hero-breakpoint: $bp-lg;
$breakpoint: $bp-md;
@ -22,125 +22,20 @@ body.catalog {
--pni-checkbox-size: 22px;
--pni-icon-size: 1.2em;
.page-header {
background: url(../_images/buyers-guide/evergreen-header-light.jpg) center
center / cover no-repeat;
.intro-text {
padding-top: 12px;
padding-bottom: 50px;
@media (min-width: $breakpoint) {
padding-top: 12px;
}
@media (min-width: $hero-breakpoint) {
padding-top: 90px;
}
}
.badge-container {
margin-top: 12px;
@media (min-width: $hero-breakpoint) {
margin-top: 32px;
}
}
.webby-award-badge {
width: 76px;
height: auto;
@media (min-width: $hero-breakpoint) {
width: 125px;
}
}
}
#product-filter-search {
background-color: $white;
cursor: pointer;
display: flex;
align-items: center;
padding: 1em;
width: 100%;
height: var(--search-box-height);
box-sizing: border-box;
text-align: left;
border: 1px solid $black;
border-radius: 2em;
transition: border-color 0.2s, width 0.2s;
margin: auto;
@media (min-width: $bp-md) {
--container-padding: 0.5em;
padding: var(--container-padding);
padding-right: 1em;
overflow: hidden;
&::placeholder {
color: transparent;
}
}
&:focus-within,
&.has-content {
border-color: $black;
cursor: default;
.search-icon {
cursor: default;
}
}
&:focus-within.has-content {
border-color: $light-blue;
.clear-icon {
background: url(../_images/buyers-guide/filter/clear-icon-blue.svg);
}
}
.search-icon {
#product-filter-search,
#pni-mobile-container {
& .clear-icon {
flex: 0 0 auto;
display: inline-block;
background: url(../_images/buyers-guide/filter/search.svg);
background-size: 22px 22px;
background-repeat: no-repeat;
display: none;
cursor: pointer;
height: var(--search-icon-size-mobile);
width: var(--search-icon-size-mobile);
margin: 0 8px 0 4px;
@media (min-width: $bp-sm) {
height: var(--search-icon-size-desktop);
width: var(--search-icon-size-desktop);
margin: 0 16px 0 8px;
}
}
input {
flex: 1 1 auto;
border: none;
outline: 0;
&::placeholder,
&::-webkit-input-placeholder {
color: $gray-40;
}
& + .clear-icon {
flex: 0 0 auto;
display: none;
cursor: pointer;
outline: 0;
padding: 0;
margin: 0;
margin-right: 4px;
height: var(--clear-icon-size);
width: var(--clear-icon-size);
background: url(../_images/buyers-guide/filter/clear-icon-black.svg);
background-size: 100% 100%;
}
padding: 0;
margin: 0;
margin-right: 4px;
height: var(--clear-icon-size);
width: var(--clear-icon-size);
background: url(../_images/buyers-guide/filter/clear-icon-blue.svg);
background-size: 100% 100%;
}
&.has-content .clear-icon {

Просмотреть файл

@ -36,6 +36,14 @@
color: $black;
font-weight: $btn-font-weight;
&.pni-nav-link {
text-decoration: none;
&:hover {
text-decoration: wavy $pni-wavy-blue 2px underline;
text-underline-offset: 0.5rem;
}
}
@media (min-width: $bp-md) {
&:not(:last-of-type) {
margin-right: 1rem;