9087 - New Navigation (#9270)
* 9087 - New Navigation * 9087 - New Navigation * Include mobile search functionality and feedback * Fix tests * Fixed donate button
This commit is contained in:
Родитель
2e94c411d4
Коммит
c3ed04434e
|
@ -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"> </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 'Buyer’s 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 'Buyer’s 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"> </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"> </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"> </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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче