[Main Nav] Frontend work (#12220)
This commit is contained in:
Родитель
881098aa74
Коммит
09068d23c2
|
@ -8294,7 +8294,7 @@ a.text-gray-dark:focus, a.text-gray-dark:hover {
|
||||||
padding-bottom: calc( + 22px - 6px / 2); } }
|
padding-bottom: calc( + 22px - 6px / 2); } }
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
#primary-nav-container .nav-links a {
|
#primary-nav-container .nav-links a {
|
||||||
padding-bottom: calc( 16px + 9px - 6px / 2); } }
|
padding-bottom: 1rem; } }
|
||||||
#primary-nav-container .nav-links a:focus, #primary-nav-container .nav-links a:active, #primary-nav-container .nav-links a:hover {
|
#primary-nav-container .nav-links a:focus, #primary-nav-container .nav-links a:active, #primary-nav-container .nav-links a:hover {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-bottom-color: #cccccc; }
|
border-bottom-color: #cccccc; }
|
||||||
|
|
|
@ -70,7 +70,7 @@ class NavFeaturedItem(BaseLinkBlock):
|
||||||
value_class = NavItemValue
|
value_class = NavItemValue
|
||||||
label = "Featured Navigation Link"
|
label = "Featured Navigation Link"
|
||||||
icon = "link"
|
icon = "link"
|
||||||
template = "nav/blocks/featured_item_block.html"
|
template = "fragments/blocks/nav/featured-item.html"
|
||||||
|
|
||||||
|
|
||||||
register(BaseLinkBlockAdapter(), NavFeaturedItem)
|
register(BaseLinkBlockAdapter(), NavFeaturedItem)
|
||||||
|
@ -81,7 +81,7 @@ class NavButton(BaseLinkBlock):
|
||||||
value_class = NavItemValue
|
value_class = NavItemValue
|
||||||
label = "Navigation Button"
|
label = "Navigation Button"
|
||||||
icon = "link"
|
icon = "link"
|
||||||
template = "nav/blocks/nav_button_block.html"
|
template = "fragments/blocks/nav/button.html"
|
||||||
|
|
||||||
|
|
||||||
register(BaseLinkBlockAdapter(), NavButton)
|
register(BaseLinkBlockAdapter(), NavButton)
|
||||||
|
@ -93,7 +93,7 @@ class NavColumnValue(blocks.StructValue):
|
||||||
return bool(self.get("button"))
|
return bool(self.get("button"))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def button(self) -> NavButton | None:
|
def button_value(self) -> NavButton | None:
|
||||||
button = self.get("button")
|
button = self.get("button")
|
||||||
if button:
|
if button:
|
||||||
return button[0]
|
return button[0]
|
||||||
|
@ -117,7 +117,7 @@ class NavColumn(blocks.StructBlock):
|
||||||
class Meta:
|
class Meta:
|
||||||
label = "Navigation Column"
|
label = "Navigation Column"
|
||||||
icon = "list-ul"
|
icon = "list-ul"
|
||||||
template = "nav/blocks/nav_column_block.html"
|
template = "fragments/blocks/nav/column.html"
|
||||||
value_class = NavColumnValue
|
value_class = NavColumnValue
|
||||||
|
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ class NavFeaturedColumn(blocks.StructBlock):
|
||||||
class Meta:
|
class Meta:
|
||||||
label = "Featured Navigation Column"
|
label = "Featured Navigation Column"
|
||||||
icon = "list-ul"
|
icon = "list-ul"
|
||||||
template = "nav/blocks/featured_column_block.html"
|
template = "fragments/blocks/nav/featured-column.html"
|
||||||
value_class = NavColumnValue
|
value_class = NavColumnValue
|
||||||
|
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ class NavOverview(blocks.StructBlock):
|
||||||
class Meta:
|
class Meta:
|
||||||
label = "Navigation Overview"
|
label = "Navigation Overview"
|
||||||
icon = "pilcrow"
|
icon = "pilcrow"
|
||||||
template = "nav/blocks/overview_block.html"
|
template = "fragments/blocks/nav/overview.html"
|
||||||
|
|
||||||
|
|
||||||
class NavDropdownValue(blocks.StructValue):
|
class NavDropdownValue(blocks.StructValue):
|
||||||
|
@ -149,7 +149,7 @@ class NavDropdownValue(blocks.StructValue):
|
||||||
return bool(self.get("overview"))
|
return bool(self.get("overview"))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def overview(self) -> NavOverview | None:
|
def overview_value(self) -> NavOverview | None:
|
||||||
overview = self.get("overview")
|
overview = self.get("overview")
|
||||||
if overview:
|
if overview:
|
||||||
return overview[0]
|
return overview[0]
|
||||||
|
@ -160,7 +160,7 @@ class NavDropdownValue(blocks.StructValue):
|
||||||
return bool(self.get("button"))
|
return bool(self.get("button"))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def button(self) -> NavButton | None:
|
def button_value(self) -> NavButton | None:
|
||||||
button = self.get("button")
|
button = self.get("button")
|
||||||
if button:
|
if button:
|
||||||
return button[0]
|
return button[0]
|
||||||
|
@ -171,12 +171,21 @@ class NavDropdownValue(blocks.StructValue):
|
||||||
return bool(self.get("featured_column"))
|
return bool(self.get("featured_column"))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def featured_column(self) -> NavFeaturedColumn | None:
|
def featured_column_value(self) -> NavFeaturedColumn | None:
|
||||||
featured_column = self.get("featured_column")
|
featured_column = self.get("featured_column")
|
||||||
if featured_column:
|
if featured_column:
|
||||||
return featured_column[0]
|
return featured_column[0]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ncols(self) -> int:
|
||||||
|
ncols = len(self.get("columns"))
|
||||||
|
if self.has_overview:
|
||||||
|
ncols += 1
|
||||||
|
if self.has_featured_column:
|
||||||
|
ncols += 1
|
||||||
|
return ncols
|
||||||
|
|
||||||
|
|
||||||
class NavDropdown(blocks.StructBlock):
|
class NavDropdown(blocks.StructBlock):
|
||||||
title = blocks.CharBlock(max_length=100, help_text="How the dropdown menu will be labelled in the nav bar")
|
title = blocks.CharBlock(max_length=100, help_text="How the dropdown menu will be labelled in the nav bar")
|
||||||
|
@ -285,5 +294,5 @@ class NavDropdown(blocks.StructBlock):
|
||||||
class Meta:
|
class Meta:
|
||||||
label = "Navigation Dropdown"
|
label = "Navigation Dropdown"
|
||||||
icon = "bars"
|
icon = "bars"
|
||||||
template = "nav/blocks/nav_dropdown_block.html"
|
template = "fragments/blocks/nav/dropdown.html"
|
||||||
value_class = NavDropdownValue
|
value_class = NavDropdownValue
|
||||||
|
|
|
@ -53,6 +53,8 @@ class NavMenu(
|
||||||
|
|
||||||
@register_setting
|
@register_setting
|
||||||
class SiteNavMenu(BaseSiteSetting):
|
class SiteNavMenu(BaseSiteSetting):
|
||||||
|
select_related = ["active_nav_menu"]
|
||||||
|
|
||||||
active_nav_menu = models.ForeignKey(
|
active_nav_menu = models.ForeignKey(
|
||||||
"nav.NavMenu",
|
"nav.NavMenu",
|
||||||
null=True,
|
null=True,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import wagtail_factories
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from wagtail.blocks import StreamBlockValidationError, StructBlockValidationError
|
from wagtail.blocks import StreamBlockValidationError, StructBlockValidationError
|
||||||
from wagtail.models import Locale, Page
|
from wagtail.models import Locale, Page
|
||||||
|
@ -138,9 +139,9 @@ class TestNavColumnBlock(TestCase):
|
||||||
for link in block["nav_items"]:
|
for link in block["nav_items"]:
|
||||||
self.assertIsInstance(link.block, nav_blocks.NavItem)
|
self.assertIsInstance(link.block, nav_blocks.NavItem)
|
||||||
self.assertIsInstance(link, nav_blocks.NavItemValue)
|
self.assertIsInstance(link, nav_blocks.NavItemValue)
|
||||||
self.assertIsNotNone(block.button)
|
self.assertIsNotNone(block.button_value)
|
||||||
self.assertEqual(len(block["button"]), 1)
|
self.assertEqual(len(block["button"]), 1)
|
||||||
self.assertEqual(block.button, block["button"][0])
|
self.assertEqual(block.button_value, block["button"][0])
|
||||||
self.assertTrue(block.has_button)
|
self.assertTrue(block.has_button)
|
||||||
|
|
||||||
def test_without_button(self):
|
def test_without_button(self):
|
||||||
|
@ -149,7 +150,7 @@ class TestNavColumnBlock(TestCase):
|
||||||
|
|
||||||
self.assertEqual(len(block["button"]), 0)
|
self.assertEqual(len(block["button"]), 0)
|
||||||
self.assertFalse(block.has_button)
|
self.assertFalse(block.has_button)
|
||||||
self.assertIsNone(block.button)
|
self.assertIsNone(block.button_value)
|
||||||
|
|
||||||
def test_with_variable_number_of_links(self):
|
def test_with_variable_number_of_links(self):
|
||||||
"""Create a nav_blocks.NavColumn with links."""
|
"""Create a nav_blocks.NavColumn with links."""
|
||||||
|
@ -247,7 +248,7 @@ class TestNavDropdownBlock(TestCase):
|
||||||
|
|
||||||
self.assertEqual(len(block["overview"]), 0)
|
self.assertEqual(len(block["overview"]), 0)
|
||||||
self.assertFalse(block.has_overview)
|
self.assertFalse(block.has_overview)
|
||||||
self.assertIsNone(block.overview)
|
self.assertIsNone(block.overview_value)
|
||||||
|
|
||||||
self.assertEqual(len(block["columns"]), 4)
|
self.assertEqual(len(block["columns"]), 4)
|
||||||
for column in block["columns"]:
|
for column in block["columns"]:
|
||||||
|
@ -256,12 +257,14 @@ class TestNavDropdownBlock(TestCase):
|
||||||
|
|
||||||
self.assertEqual(len(block["featured_column"]), 0)
|
self.assertEqual(len(block["featured_column"]), 0)
|
||||||
self.assertFalse(block.has_featured_column)
|
self.assertFalse(block.has_featured_column)
|
||||||
self.assertIsNone(block.featured_column)
|
self.assertIsNone(block.featured_column_value)
|
||||||
|
|
||||||
self.assertEqual(len(block["button"]), 1)
|
self.assertEqual(len(block["button"]), 1)
|
||||||
self.assertIsInstance(block["button"][0].block, nav_blocks.NavButton)
|
self.assertIsInstance(block["button"][0].block, nav_blocks.NavButton)
|
||||||
self.assertTrue(block.has_button)
|
self.assertTrue(block.has_button)
|
||||||
self.assertEqual(block.button, block["button"][0])
|
self.assertEqual(block.button_value, block["button"][0])
|
||||||
|
|
||||||
|
self.assertEqual(block.ncols, 4)
|
||||||
|
|
||||||
def test_block_with_overview(self):
|
def test_block_with_overview(self):
|
||||||
"""Create a nav_blocks.NavDropdown with an overview."""
|
"""Create a nav_blocks.NavDropdown with an overview."""
|
||||||
|
@ -270,10 +273,12 @@ class TestNavDropdownBlock(TestCase):
|
||||||
|
|
||||||
self.assertEqual(len(block["overview"]), 1)
|
self.assertEqual(len(block["overview"]), 1)
|
||||||
self.assertTrue(block.has_overview)
|
self.assertTrue(block.has_overview)
|
||||||
self.assertEqual(block.overview, block["overview"][0])
|
self.assertEqual(block.overview_value, block["overview"][0])
|
||||||
|
|
||||||
self.assertEqual(len(block["columns"]), 3)
|
self.assertEqual(len(block["columns"]), 3)
|
||||||
|
|
||||||
|
self.assertEqual(block.ncols, 4)
|
||||||
|
|
||||||
def test_block_with_featured_column(self):
|
def test_block_with_featured_column(self):
|
||||||
"""Create a nav_blocks.NavDropdown with a featured column."""
|
"""Create a nav_blocks.NavDropdown with a featured column."""
|
||||||
block = nav_factories.NavDropdownFactory(with_featured_column=True)
|
block = nav_factories.NavDropdownFactory(with_featured_column=True)
|
||||||
|
@ -281,10 +286,12 @@ class TestNavDropdownBlock(TestCase):
|
||||||
|
|
||||||
self.assertEqual(len(block["featured_column"]), 1)
|
self.assertEqual(len(block["featured_column"]), 1)
|
||||||
self.assertTrue(block.has_featured_column)
|
self.assertTrue(block.has_featured_column)
|
||||||
self.assertEqual(block.featured_column, block["featured_column"][0])
|
self.assertEqual(block.featured_column_value, block["featured_column"][0])
|
||||||
|
|
||||||
self.assertEqual(len(block["columns"]), 3)
|
self.assertEqual(len(block["columns"]), 3)
|
||||||
|
|
||||||
|
self.assertEqual(block.ncols, 4)
|
||||||
|
|
||||||
def test_block_with_overview_and_featured_column(self):
|
def test_block_with_overview_and_featured_column(self):
|
||||||
"""Create a nav_blocks.NavDropdown with an overview and a featured column."""
|
"""Create a nav_blocks.NavDropdown with an overview and a featured column."""
|
||||||
block = nav_factories.NavDropdownFactory(with_overview_and_featured_column=True)
|
block = nav_factories.NavDropdownFactory(with_overview_and_featured_column=True)
|
||||||
|
@ -292,14 +299,62 @@ class TestNavDropdownBlock(TestCase):
|
||||||
|
|
||||||
self.assertEqual(len(block["overview"]), 1)
|
self.assertEqual(len(block["overview"]), 1)
|
||||||
self.assertTrue(block.has_overview)
|
self.assertTrue(block.has_overview)
|
||||||
self.assertEqual(block.overview, block["overview"][0])
|
self.assertEqual(block.overview_value, block["overview"][0])
|
||||||
|
|
||||||
self.assertEqual(len(block["featured_column"]), 1)
|
self.assertEqual(len(block["featured_column"]), 1)
|
||||||
self.assertTrue(block.has_featured_column)
|
self.assertTrue(block.has_featured_column)
|
||||||
self.assertEqual(block.featured_column, block["featured_column"][0])
|
self.assertEqual(block.featured_column_value, block["featured_column"][0])
|
||||||
|
|
||||||
self.assertEqual(len(block["columns"]), 2)
|
self.assertEqual(len(block["columns"]), 2)
|
||||||
|
|
||||||
|
self.assertEqual(block.ncols, 4)
|
||||||
|
|
||||||
|
def test_number_of_cols_prop(self):
|
||||||
|
"""Test the number of columns property."""
|
||||||
|
block = nav_factories.NavDropdownFactory()
|
||||||
|
nav_blocks.NavDropdown().clean(block)
|
||||||
|
|
||||||
|
self.assertEqual(block.ncols, 4)
|
||||||
|
|
||||||
|
block = nav_factories.NavDropdownFactory(
|
||||||
|
columns=wagtail_factories.ListBlockFactory(
|
||||||
|
nav_factories.NavColumnFactory,
|
||||||
|
**{
|
||||||
|
"0__title": "Column 1",
|
||||||
|
"1__title": "Column 2",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
nav_blocks.NavDropdown().clean(block)
|
||||||
|
self.assertEqual(block.ncols, 2)
|
||||||
|
|
||||||
|
block = nav_factories.NavDropdownFactory(
|
||||||
|
columns=wagtail_factories.ListBlockFactory(
|
||||||
|
nav_factories.NavColumnFactory,
|
||||||
|
**{
|
||||||
|
"0__title": "Column 1",
|
||||||
|
"1__title": "Column 2",
|
||||||
|
"2__title": "Column 3",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
nav_blocks.NavDropdown().clean(block)
|
||||||
|
self.assertEqual(block.ncols, 3)
|
||||||
|
|
||||||
|
block = nav_factories.NavDropdownFactory(
|
||||||
|
columns=wagtail_factories.ListBlockFactory(
|
||||||
|
nav_factories.NavColumnFactory,
|
||||||
|
**{
|
||||||
|
"0__title": "Column 1",
|
||||||
|
"1__title": "Column 2",
|
||||||
|
"2__title": "Column 3",
|
||||||
|
"3__title": "Column 4",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
nav_blocks.NavDropdown().clean(block)
|
||||||
|
self.assertEqual(block.ncols, 4)
|
||||||
|
|
||||||
def test_block_without_button(self):
|
def test_block_without_button(self):
|
||||||
"""Create a nav_blocks.NavDropdown without a button."""
|
"""Create a nav_blocks.NavDropdown without a button."""
|
||||||
block = nav_factories.NavDropdownFactory(no_button=True)
|
block = nav_factories.NavDropdownFactory(no_button=True)
|
||||||
|
@ -307,7 +362,7 @@ class TestNavDropdownBlock(TestCase):
|
||||||
|
|
||||||
self.assertEqual(len(block["button"]), 0)
|
self.assertEqual(len(block["button"]), 0)
|
||||||
self.assertFalse(block.has_button)
|
self.assertFalse(block.has_button)
|
||||||
self.assertIsNone(block.button)
|
self.assertIsNone(block.button_value)
|
||||||
|
|
||||||
def test_needs_at_least_one_column(self):
|
def test_needs_at_least_one_column(self):
|
||||||
with self.assertRaises(StructBlockValidationError):
|
with self.assertRaises(StructBlockValidationError):
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
from pattern_library.monkey_utils import override_tag
|
||||||
|
from wagtail.images.templatetags.wagtailimages_tags import register
|
||||||
|
|
||||||
|
override_tag(register, name="image", default_html="")
|
|
@ -0,0 +1,6 @@
|
||||||
|
from pattern_library.monkey_utils import override_tag
|
||||||
|
from wagtail.templatetags.wagtailcore_tags import register
|
||||||
|
|
||||||
|
override_tag(register, name="include_block", default_html="")
|
||||||
|
override_tag(register, name="pageurl", default_html="/")
|
||||||
|
override_tag(register, name="slugurl", default_html="")
|
|
@ -520,6 +520,8 @@ WAGTAILIMAGES_INDEX_PAGE_SIZE = env("WAGTAILIMAGES_INDEX_PAGE_SIZE")
|
||||||
WAGTAIL_USAGE_COUNT_ENABLED = True
|
WAGTAIL_USAGE_COUNT_ENABLED = True
|
||||||
WAGTAIL_I18N_ENABLED = True
|
WAGTAIL_I18N_ENABLED = True
|
||||||
|
|
||||||
|
WAGTAILIMAGES_EXTENSIONS = ["avif", "gif", "jpg", "jpeg", "png", "webp", "svg"]
|
||||||
|
|
||||||
# Wagtail Frontend Cache Invalidator Settings
|
# Wagtail Frontend Cache Invalidator Settings
|
||||||
|
|
||||||
if env("FRONTEND_CACHE_CLOUDFLARE_BEARER_TOKEN"):
|
if env("FRONTEND_CACHE_CLOUDFLARE_BEARER_TOKEN"):
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
{% load static wagtailadmin_tags %}
|
||||||
|
|
||||||
|
{% if style == "primary" %}
|
||||||
|
{% fragment as nav_button_style %}tw-btn-primary tw-py-4 tw-px-8{% endfragment %}
|
||||||
|
{% elif style == "primary-full-width" %}
|
||||||
|
{% fragment as nav_button_style %}tw-btn-primary tw-min-w-full tw-py-4 tw-px-8{% endfragment %}
|
||||||
|
{% elif style == "cta" %}
|
||||||
|
{% fragment as nav_button_style %}tw-leading-[130%] tw-text-blue-80 tw-p-2 hover:tw-underline{% endfragment %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% fragment as base_styles %}link-button tw-font-bold tw-text-lg{% endfragment %}
|
||||||
|
|
||||||
|
<a class="{{ nav_button_style }} {{ base_styles }} after:tw-content-['_→'] after:tw-font-['Nunito_Sans']" href="{{ value.url }}" {% if value.open_in_new_window %}target="_blank"{% endif %}>{{ value.label }}</a>
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Navigation Button
|
||||||
|
|
||||||
|
A call-to-action to a page, relative URL or external URL.
|
||||||
|
|
||||||
|
Takes one of the following `style` options:
|
||||||
|
* `primary` (for a solid primary button)
|
||||||
|
* `primary-full-width` (for a solid primary button with 100% width of the container%)
|
||||||
|
* `cta` (for blue text on white background)
|
|
@ -0,0 +1,7 @@
|
||||||
|
name: Navigation Button
|
||||||
|
context:
|
||||||
|
value:
|
||||||
|
label: "Learn more"
|
||||||
|
url: https://google.com
|
||||||
|
open_in_new_window: False
|
||||||
|
style: primary
|
|
@ -0,0 +1,16 @@
|
||||||
|
{% load wagtailcore_tags wagtailadmin_tags %}
|
||||||
|
|
||||||
|
{% fragment as base_styles %}tw-flex tw-flex-col tw-items-start tw-gap-8 tw-py-8{% endfragment %}
|
||||||
|
{% fragment as desktop_layout %}large:tw-py-22 large:tw-px-8 large:tw-ms-9 large:tw-col-span-1{% endfragment %}
|
||||||
|
|
||||||
|
<div class="{{ base_styles }} {{ desktop_layout }}">
|
||||||
|
<h6 class="tw-self-stretch">{{ value.title }}</h6>
|
||||||
|
<div class="tw-flex tw-flex-col tw-items-start tw-gap-8 tw-self-stretch">
|
||||||
|
{% for item in value.nav_items %}
|
||||||
|
<div class="tw-self-stretch">{% include_block item %}</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% if value.has_button %}
|
||||||
|
<div class="tw-self-stretch">{% include_block value.button_value with style="cta" %}</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,34 @@
|
||||||
|
name: Navigation Column
|
||||||
|
context:
|
||||||
|
value:
|
||||||
|
title: "Research & Analysis"
|
||||||
|
nav_items:
|
||||||
|
- value:
|
||||||
|
label: "Trustworthy AI Progress Report"
|
||||||
|
description: "Promoting openness, competition, and accountability in AI"
|
||||||
|
url: /foo/bar
|
||||||
|
is_external: false
|
||||||
|
- value:
|
||||||
|
label: "Internet Health Report"
|
||||||
|
description: "Issues impacting a healthy internet"
|
||||||
|
url: /foo/bar
|
||||||
|
is_external: true
|
||||||
|
- value:
|
||||||
|
label: "AI Policy"
|
||||||
|
description: "Policy recommendations for AI"
|
||||||
|
url: /foo/bar
|
||||||
|
is_external: false
|
||||||
|
has_button: true
|
||||||
|
button:
|
||||||
|
value:
|
||||||
|
label: "See all research"
|
||||||
|
url: /foo/bar
|
||||||
|
is_external: false
|
||||||
|
style: "cta-link"
|
||||||
|
|
||||||
|
tags:
|
||||||
|
include_block:
|
||||||
|
'item':
|
||||||
|
template_name: "fragments/blocks/nav/item.html"
|
||||||
|
'value.button with style="cta-link"':
|
||||||
|
template_name: "fragments/blocks/nav/variants/button--cta-link.html"
|
|
@ -0,0 +1,46 @@
|
||||||
|
{% load static wagtailcore_tags wagtailadmin_tags %}
|
||||||
|
|
||||||
|
{% fragment as title_base_typography %}tw-font-sans tw-font-bold tw-text-xl tw-capitalize tw-text-black{% endfragment %}
|
||||||
|
{% fragment as content_base_styles %}tw-py-0 tw-px-8 tw-gap-8 tw-overflow-y-auto{% endfragment %}
|
||||||
|
{% fragment as dropdown_selector_base %}tw-flex tw-flex-row tw-items-center tw-justify-between tw-w-full tw-py-12 tw-px-8 tw-gap-4{% endfragment %}
|
||||||
|
|
||||||
|
{% fragment as content_desktop %}large:tw-container large:tw-hidden{% endfragment %}
|
||||||
|
{% fragment as content_desktop_border %}large:tw-border large:tw-border-gray-20{% endfragment %}
|
||||||
|
{% comment %} 5rem is the height of the navbar and 1px is the size of the dropdown's border {% endcomment %}
|
||||||
|
{% fragment as content_desktop_positioning %}large:tw-fixed large:tw-top-[calc(5rem+1px)] large:tw-left-0 large:tw-right-0 large:tw-mx-auto{% endfragment %}
|
||||||
|
|
||||||
|
{% fragment as title_desktop_typography %}large:tw-text-lg large:tw-text-black{% endfragment %}
|
||||||
|
|
||||||
|
|
||||||
|
{% comment %} 2.5rem for half the navbar's height, 14px for half the title's line height, 6px for the title bottom border and 1 px for the dropdown border:{% endcomment %}
|
||||||
|
<div class="tw-flex tw-flex-col large:tw-border-b-6 large:tw-pt-[calc(2.5rem-14px)] large:tw-pb-[calc(2.5rem-14px-6px+1px)] large:tw-border-invisible"
|
||||||
|
data-{{ style }}-dropdown
|
||||||
|
>
|
||||||
|
<div class="{{ dropdown_selector_base }} large:tw-items-center large:tw-py-0 " data-accordion-title>
|
||||||
|
<h5 class="tw-m-0 {{ title_base_typography }} {{ title_desktop_typography }}">{{ value.title }}</h5>
|
||||||
|
<img src="{% static "_images/chevron.svg" %}" height="18" width="18" alt="" class="tw-w-8 tw-h-auto tw-rotate-180 tw-transition-transform large:tw-hidden">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="{{ content_base_styles }} {{ content_desktop_positioning }} {{ content_desktop }}" data-accordion-content>
|
||||||
|
<div class="tw-flex tw-flex-col tw-p-0 tw-bg-white tw-gap-8 {{ content_desktop_border }} large:tw-grid large:tw-w-{{ value.ncols }}/4 large:tw-grid-cols-{{ value.ncols }}" >
|
||||||
|
{% if value.has_overview %}
|
||||||
|
{% include_block value.overview_value with button=value.button_value %}
|
||||||
|
{% endif %}
|
||||||
|
{% for column in value.columns %}
|
||||||
|
{% include_block column %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if value.has_featured_column %}
|
||||||
|
{% include_block value.featured_column_value %}
|
||||||
|
{% endif %}
|
||||||
|
{% comment %}
|
||||||
|
If there is a button but no overview, we want to render the button at the bottom
|
||||||
|
of the dropdown. Otherwise it will be rendered together with the overview.
|
||||||
|
{% endcomment %}
|
||||||
|
{% if value.has_button and not value.has_overview %}
|
||||||
|
<div class="tw-w-full tw-pb-16 large:tw-col-span-4 large:tw-py-0">
|
||||||
|
{% include_block value.button_value with style="primary-full-width" %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Navigation Dropdown
|
||||||
|
|
||||||
|
A collection of navigation columns.
|
|
@ -0,0 +1,29 @@
|
||||||
|
name: Navigation Dropdown
|
||||||
|
context:
|
||||||
|
value:
|
||||||
|
title: "Who We Are"
|
||||||
|
has_overview: True
|
||||||
|
overview:
|
||||||
|
title: About Us
|
||||||
|
description: "Mozilla is a global nonprofit dedicated to keeping the Internet a public resource that is open and accessible to all."
|
||||||
|
columns:
|
||||||
|
- column:
|
||||||
|
- column:
|
||||||
|
has_featured_column: true
|
||||||
|
featured_column:
|
||||||
|
- featured_column:
|
||||||
|
has_button: true
|
||||||
|
button:
|
||||||
|
- button:
|
||||||
|
style: mobile
|
||||||
|
|
||||||
|
tags:
|
||||||
|
include_block:
|
||||||
|
'value.overview|first with button=value.button|first':
|
||||||
|
template_name: "fragments/blocks/nav/overview.html"
|
||||||
|
'column':
|
||||||
|
template_name: "fragments/blocks/nav/column.html"
|
||||||
|
'value.button|first with style="primary-full-width"':
|
||||||
|
template_name: "fragments/blocks/nav/variants/button--primary-full-width.html"
|
||||||
|
'value.featured_column|first':
|
||||||
|
template_name: "fragments/blocks/nav/featured-column.html"
|
|
@ -0,0 +1,13 @@
|
||||||
|
{% load wagtailcore_tags wagtailadmin_tags %}
|
||||||
|
|
||||||
|
{% fragment as base_styles %}tw-flex tw-flex-col tw-items-start tw-gap-12 tw-py-8 tw-px-12 tw-bg-gray-02 tw-rounded-2xl{% endfragment %}
|
||||||
|
{% fragment as desktop_layout %}large:tw-py-22 large:tw-px-8 large:tw-ms-9 large:tw-rounded-none large:tw-col-span-1{% endfragment %}
|
||||||
|
|
||||||
|
<div class="{{ base_styles }} {{ desktop_layout }}">
|
||||||
|
<h6 class="tw-self-stretch">{{ value.title }}</h6>
|
||||||
|
<div class="tw-flex tw-flex-col tw-items-start tw-gap-8 tw-self-stretch">
|
||||||
|
{% for item in value.nav_items %}
|
||||||
|
<div class="tw-self-stretch">{% include_block item %}</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,18 @@
|
||||||
|
name: Navigation Featured Column
|
||||||
|
context:
|
||||||
|
value:
|
||||||
|
title: "Donate"
|
||||||
|
nav_items:
|
||||||
|
- value:
|
||||||
|
label: "Make a Donation"
|
||||||
|
url: /foo/bar
|
||||||
|
is_external: false
|
||||||
|
- value:
|
||||||
|
label: "Ways to Give"
|
||||||
|
url: /foo/bar
|
||||||
|
is_external: true
|
||||||
|
|
||||||
|
tags:
|
||||||
|
include_block:
|
||||||
|
'item':
|
||||||
|
template_name: "fragments/blocks/nav/featured-item.html"
|
|
@ -0,0 +1,12 @@
|
||||||
|
{% load static i18n wagtailadmin_tags wagtailimages_tags %}
|
||||||
|
|
||||||
|
{% fragment as font_styles %}tw-text-xl large:tw-text-lg tw-font-semibold tw-text-black{% endfragment %}
|
||||||
|
{% fragment as hover_styles %}group-hover/item:tw-text-blue-80 group-hover/item:tw-underline{% endfragment %}
|
||||||
|
|
||||||
|
<div class="tw-group/item tw-flex tw-flex-row tw-self-stretch tw-gap-6 tw-p-4 hover:tw-bg-blue-03">
|
||||||
|
{% image value.icon fill-18x18 preserve-svg %}
|
||||||
|
<a class="{{ font_styles }} {{ hover_styles }}"
|
||||||
|
href="{{ value.url }}" {% if value.is_external %}target="_blank"{% endif %}>
|
||||||
|
{{ value.label }}
|
||||||
|
</a>
|
||||||
|
</div>
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Navigation Featured Item
|
||||||
|
|
||||||
|
A featured item in the navigation menu, holding a title, an icon and a link to a resource.
|
|
@ -0,0 +1,13 @@
|
||||||
|
name: Navigation Featured Item
|
||||||
|
context:
|
||||||
|
value:
|
||||||
|
label: "Make a Donation"
|
||||||
|
icon:
|
||||||
|
url: /donate
|
||||||
|
is_external: True
|
||||||
|
|
||||||
|
tags:
|
||||||
|
image:
|
||||||
|
value.icon fill-18x18 preserve-svg:
|
||||||
|
raw:
|
||||||
|
'<img src="http://localhost:8000/images/AsaYTU0vcnQ3JEbiEoPxhIAbmKI=/9977/original/" width="18" height="18" alt=""/>'
|
|
@ -1,11 +1,10 @@
|
||||||
{% load static i18n wagtailadmin_tags %}
|
{% load static i18n wagtailadmin_tags %}
|
||||||
|
|
||||||
{% fragment as font_styles %}tw-text-xl tw-font-semibold tw-capitalize tw-text-black{% endfragment %}
|
{% fragment as font_styles %}tw-text-xl large:tw-text-lg tw-font-semibold tw-text-black{% endfragment %}
|
||||||
{% fragment as hover_styles %}group-hover:tw-text-blue-80 group-hover:tw-underline{% endfragment %}
|
{% fragment as hover_styles %}group-hover/item:tw-text-blue-80 group-hover/item:tw-underline{% endfragment %}
|
||||||
{% fragment as after_arrow_styles %}after:tw-content-['_↗'] after:tw-font-['Nunito_Sans'] after:tw-text-gray-20 group-hover:after:tw-text-blue-80{% endfragment %}
|
|
||||||
|
|
||||||
<div class="tw-group tw-flex tw-flex-col tw-gap-2 tw-p-2 hover:tw-bg-blue-03">
|
<div class="tw-group/item tw-flex tw-flex-col tw-gap-4 tw-p-4 hover:tw-bg-blue-03 hover:tw-rounded">
|
||||||
<a class="{{ font_styles }} {% if value.is_external %} {{ after_arrow_styles }} {% endif %} {{ hover_styles }}"
|
<a class="{{ font_styles }} {% if value.is_external %} after:tw-content-['_↗'] after:tw-font-['Nunito_Sans'] after:tw-text-gray-20 group-hover/item:after:tw-text-blue-80 {% endif %} {{ hover_styles }}"
|
||||||
href="{{ value.url }}" {% if value.is_external %}target="_blank"{% endif %}>
|
href="{{ value.url }}" {% if value.is_external %}target="_blank"{% endif %}>
|
||||||
{{ value.label }}
|
{{ value.label }}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
{% load wagtailcore_tags wagtailadmin_tags %}
|
||||||
|
|
||||||
|
{% fragment as base_styles %}tw-flex tw-flex-col tw-items-start tw-gap-14 tw-pb-16{% endfragment %}
|
||||||
|
{% fragment as border_styles %}tw-border-gray-20 tw-border-b-[1px] large:tw-border-b-0 large:tw-border-r-[1px]{% endfragment %}
|
||||||
|
{% fragment as desktop_layout %}large:tw-col-span-1 large:tw-my-22 large:tw-pb-0 large:tw-ms-8 large:tw-ps-12 large:tw-pe-8 large:tw-border-r{% endfragment %}
|
||||||
|
|
||||||
|
<div class="{{ base_styles }} {{ border_styles }} {{ desktop_layout }}">
|
||||||
|
<div class="tw-flex tw-flex-col tw-items-start tw-gap-10">
|
||||||
|
<p class="tw-font-zilla tw-italic tw-font-medium tw-text-2xl tw-text-black tw-my-0 tw-py-0">{{ value.title }}</p>
|
||||||
|
<div class="[&_p]:tw-text-gray-80 [&_p]:tw-text-base [&_p]:tw-font-normal [&_p]:tw-font-sans">{{ value.description|richtext }}</div>
|
||||||
|
</div>
|
||||||
|
{% if button %}
|
||||||
|
{% include_block button with style="primary" %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Navigation Overview
|
||||||
|
|
||||||
|
A block with a title and a description for the navigation dropdown menu.
|
||||||
|
|
||||||
|
Takes an optional "button" block property, which will render the button block as part of the overview block.
|
|
@ -0,0 +1,11 @@
|
||||||
|
name: Navigation Overview
|
||||||
|
context:
|
||||||
|
value:
|
||||||
|
title: About Us
|
||||||
|
description: Mozilla is a global nonprofit dedicated to keeping the Internet a public resource that is open and accessible to all.
|
||||||
|
button: True
|
||||||
|
|
||||||
|
tags:
|
||||||
|
include_block:
|
||||||
|
'button with style="primary"':
|
||||||
|
template_name: "fragments/blocks/nav/button.html"
|
|
@ -0,0 +1 @@
|
||||||
|
{% include "fragments/blocks/nav/button.html" with style="cta" %}
|
|
@ -0,0 +1 @@
|
||||||
|
{% include "fragments/blocks/nav/button.html" with style="primary-full-width" %}
|
|
@ -0,0 +1,29 @@
|
||||||
|
{% extends "fragments/primary_nav.html" %}
|
||||||
|
|
||||||
|
{% load i18n wagtailcore_tags wagtailadmin_tags %}
|
||||||
|
|
||||||
|
{% block menu_container_classes %}
|
||||||
|
{{ block.super }}
|
||||||
|
large:tw-py-0 tw-bg-white tw-relative
|
||||||
|
{% endblock menu_container_classes %}
|
||||||
|
|
||||||
|
{% block narrow_screen_menu %}
|
||||||
|
<div class="tw-bg-white tw-min-h-lvh">
|
||||||
|
<div class="tw-flex tw-flex-col tw-border-y-[1px] tw-border-gray-20 tw-divide-y-[1px] tw-divide-gray-20 tw-w-full" data-nav-accordion-menu>
|
||||||
|
{% for dropdown in menu.dropdowns %}
|
||||||
|
{% include_block dropdown with style="mobile" %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="tw-flex tw-flex-col tw-items-center tw-p-8">
|
||||||
|
<button class="tw-btn-secondary btn-newsletter tw-w-full">{% trans "Newsletter" %}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock narrow_screen_menu %}
|
||||||
|
|
||||||
|
{% block wide_screen_menu %}
|
||||||
|
<div class="tw-hidden large:tw-flex large:tw-flex-row large:tw-items-center large:tw-h-full" data-nav-accordion-menu>
|
||||||
|
{% for dropdown in menu.dropdowns %}
|
||||||
|
{% include_block dropdown with style="desktop" %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endblock wide_screen_menu %}
|
|
@ -0,0 +1,12 @@
|
||||||
|
name: Navigation Menu
|
||||||
|
context:
|
||||||
|
menu:
|
||||||
|
dropdowns:
|
||||||
|
- dropdown
|
||||||
|
- dropdown
|
||||||
|
- dropdown
|
||||||
|
|
||||||
|
tags:
|
||||||
|
include_block:
|
||||||
|
'dropdown':
|
||||||
|
template_name: "fragments/blocks/nav/dropdown.html"
|
|
@ -4,15 +4,15 @@
|
||||||
{% else %}<div class="primary-nav-container">
|
{% else %}<div class="primary-nav-container">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="wrapper-burger {% block wrapper_classes %}{% endblock %}">
|
<div class="wrapper-burger {% block wrapper_classes %}{% endblock %}">
|
||||||
<div class="menu-container {% block menu_container_classes %}{% endblock %}">
|
<div class="menu-container large:tw-h-40 {% block menu_container_classes %}{% endblock %}">
|
||||||
{% block menu_content %}
|
{% block menu_content %}
|
||||||
<div class="narrow-screen-menu hidden d-lg-none">
|
<div class="narrow-screen-menu tw-bg-white hidden d-lg-none tw-overflow-y-auto">
|
||||||
{% block narrow_screen_menu %}
|
{% block narrow_screen_menu %}
|
||||||
<div class="narrow-screen-menu-background tw-dark">
|
<div class="narrow-screen-menu-background tw-dark">
|
||||||
<div class="narrow-screen-menu-container">
|
<div class="narrow-screen-menu-container ">
|
||||||
<div class="container" role="navigation">
|
<div class="tw-container" role="navigation">
|
||||||
<div class="row">
|
<div class="tw-row">
|
||||||
<div class="col">
|
<div class="tw-flex-grow tw-max-w-full tw-flex-1">
|
||||||
<div class="nav-links pt-3">
|
<div class="nav-links pt-3">
|
||||||
{% block narrow_screen_nav_links %}
|
{% block narrow_screen_nav_links %}
|
||||||
<div><a class="{% primary_active_nav request menu_root.full_url menu_root.full_url %}" href="{{ menu_root.url }}">{% trans "Home" %}</a></div>
|
<div><a class="{% primary_active_nav request menu_root.full_url menu_root.full_url %}" href="{{ menu_root.url }}">{% trans "Home" %}</a></div>
|
||||||
|
@ -28,27 +28,27 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
<nav class="container wide-screen-menu-container" title="{% trans "main site navigation" context "Tooltip on menu items" %}">
|
<nav class="tw-container wide-screen-menu-container tw-relative large:tw-h-full tw-bg-white" title="{% trans "main site navigation" context "Tooltip on menu items" %}">
|
||||||
<div class="row">
|
<div class="tw-row tw-h-full tw-justify-between large:tw-items-center">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="d-flex flex-row justify-content-between">
|
<div class="tw-flex tw-flex-row tw-justify-between large:tw-items-center">
|
||||||
<div id="primary-nav-links" class="tw-w-full large:tw-w-auto">
|
<div id="primary-nav-links" class="tw-w-full large:tw-w-auto large:tw-py-0 large:tw-items-center">
|
||||||
<div class="d-flex align-items-center flex-wrap">
|
<div class="tw-flex tw-items-center tw-flex-wrap large:tw-h-24">
|
||||||
|
|
||||||
<button class="burger {% if page.zen_nav is not True %} d-lg-none ml-md-0 {% endif %}" aria-label="{% trans 'Open menu' %}">
|
<button class="burger tw-z-50 tw-bg-white {% if page.zen_nav is not True %} large:tw-hidden small:tw-ml-0 {% endif %}" aria-label="{% trans 'Open menu' %}">
|
||||||
<span class="burger-bar burger-bar-top"></span>
|
<span class="burger-bar burger-bar-top"></span>
|
||||||
<span class="burger-bar burger-bar-middle"></span>
|
<span class="burger-bar burger-bar-middle"></span>
|
||||||
<span class="burger-bar burger-bar-bottom"></span>
|
<span class="burger-bar burger-bar-bottom"></span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{% block nav_logo %}
|
{% block nav_logo %}
|
||||||
<a class="logo text-hide" href="/" aria-label="{% trans "Mozilla Foundation Homepage" %}">{% trans "Mozilla Foundation" %}</a>
|
<a class="logo text-hide tw-z-50" href="/" aria-label="{% trans "Mozilla Foundation Homepage" %}">{% trans "Mozilla Foundation" %}</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% if page.zen_nav == True %}
|
{% if page.zen_nav == True %}
|
||||||
<div class="wide-screen-menu hidden">
|
<div class="wide-screen-menu hidden">
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="wide-screen-menu">
|
<div class="wide-screen-menu large:tw-h-full">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% block wide_screen_menu %}
|
{% block wide_screen_menu %}
|
||||||
|
@ -79,9 +79,9 @@
|
||||||
|
|
||||||
|
|
||||||
<div id="nav-newsletter-form-wrapper" class="d-none">
|
<div id="nav-newsletter-form-wrapper" class="d-none">
|
||||||
<div class="container tw-dark">
|
<div class="tw-container tw-dark">
|
||||||
<div class="row">
|
<div class="tw-row">
|
||||||
<div class="col-12">
|
<div class="tw-relative tw-px-8 tw-w-full">
|
||||||
<div class="newsletter-signup-module on-nav tw-pt-24"
|
<div class="newsletter-signup-module on-nav tw-pt-24"
|
||||||
data-module-type="default"
|
data-module-type="default"
|
||||||
data-form-style="header:2-col"
|
data-form-style="header:2-col"
|
||||||
|
|
|
@ -107,7 +107,13 @@
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="{% block sticky_top_class %} sticky-top {% endblock %} d-print-none">
|
<div class="{% block sticky_top_class %} sticky-top {% endblock %} d-print-none">
|
||||||
{% block primary_nav %}
|
{% block primary_nav %}
|
||||||
{% include "fragments/primary_nav.html" with background="simple-background" %}
|
{% with nav_menu=settings.nav.SiteNavMenu.active_nav_menu %}
|
||||||
|
{% if nav_menu %}
|
||||||
|
{% include "fragments/nav/menu.html" with menu=nav_menu.localized %}
|
||||||
|
{% else %}
|
||||||
|
{% include "fragments/primary_nav.html" with background="simple-background" %}
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
<div class="tw-row">
|
<div class="tw-row">
|
||||||
{% include "wagtailpages/fragments/styleguide_color_block.html" with classname="tw-bg-white" name="White ($white)" hex="#ffffff" %}
|
{% include "wagtailpages/fragments/styleguide_color_block.html" with classname="tw-bg-white" name="White ($white)" hex="#ffffff" %}
|
||||||
|
|
||||||
|
{% include "wagtailpages/fragments/styleguide_color_block.html" with classname="tw-bg-gray-02" name="Gray 02" hex="#fafafa" %}
|
||||||
|
|
||||||
{% include "wagtailpages/fragments/styleguide_color_block.html" with classname="tw-bg-gray-05" name="Gray 05 ($gray-05)" hex="#f2f2f2" %}
|
{% include "wagtailpages/fragments/styleguide_color_block.html" with classname="tw-bg-gray-05" name="Gray 05 ($gray-05)" hex="#f2f2f2" %}
|
||||||
|
|
||||||
{% include "wagtailpages/fragments/styleguide_color_block.html" with classname="tw-bg-gray-20" name="Gray 20 ($gray-20)" hex="#cccccc" %}
|
{% include "wagtailpages/fragments/styleguide_color_block.html" with classname="tw-bg-gray-20" name="Gray 20 ($gray-20)" hex="#cccccc" %}
|
||||||
|
@ -53,6 +55,8 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tw-row">
|
<div class="tw-row">
|
||||||
|
{% include "wagtailpages/fragments/styleguide_color_block.html" with classname="tw-bg-blue-03" name="Blue 03" hex="#f5f5fd" %}
|
||||||
|
|
||||||
{% include "wagtailpages/fragments/styleguide_color_block.html" with classname="tw-bg-blue-05" name="Blue 05" hex="#e7e7fc" %}
|
{% include "wagtailpages/fragments/styleguide_color_block.html" with classname="tw-bg-blue-05" name="Blue 05" hex="#e7e7fc" %}
|
||||||
|
|
||||||
{% include "wagtailpages/fragments/styleguide_color_block.html" with classname="tw-bg-blue-10" name="Blue 10" hex="#d3d5fc" %}
|
{% include "wagtailpages/fragments/styleguide_color_block.html" with classname="tw-bg-blue-10" name="Blue 10" hex="#d3d5fc" %}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
class Accordion {
|
||||||
|
static selector() {
|
||||||
|
return "[data-accordion]";
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(node) {
|
||||||
|
this.accordion = node;
|
||||||
|
this.title = this.accordion.querySelector("[data-accordion-title]");
|
||||||
|
this.content = this.accordion.querySelector("[data-accordion-content]");
|
||||||
|
this.chevron = this.title.querySelector("img");
|
||||||
|
this.titleText = this.title.querySelector("h5");
|
||||||
|
this.close();
|
||||||
|
this.bindEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
bindEvents() {
|
||||||
|
this.title.addEventListener("click", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
let open = !this.content.classList.contains("tw-hidden");
|
||||||
|
|
||||||
|
if (open) {
|
||||||
|
this.close();
|
||||||
|
open = false;
|
||||||
|
} else {
|
||||||
|
this.open();
|
||||||
|
open = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.title.addEventListener("focus", () => {
|
||||||
|
this.title.setAttribute("aria-selected", "true");
|
||||||
|
});
|
||||||
|
|
||||||
|
this.title.addEventListener("blur", () => {
|
||||||
|
this.title.setAttribute("aria-selected", "false");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
open() {
|
||||||
|
this.content.classList.remove("tw-hidden");
|
||||||
|
this.chevron.classList.remove("tw-rotate-180");
|
||||||
|
this.title.setAttribute("aria-expanded", "true");
|
||||||
|
this.content.setAttribute("aria-hidden", "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.content.classList.add("tw-hidden");
|
||||||
|
this.chevron.classList.add("tw-rotate-180");
|
||||||
|
this.title.setAttribute("aria-expanded", "false");
|
||||||
|
this.content.setAttribute("aria-hidden", "true");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Accordion;
|
|
@ -0,0 +1,65 @@
|
||||||
|
import Accordion from "../accordion/accordion";
|
||||||
|
|
||||||
|
class NavDesktopDropdown extends Accordion {
|
||||||
|
static selector() {
|
||||||
|
return "[data-desktop-dropdown]";
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(node) {
|
||||||
|
super(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
getSiblings() {
|
||||||
|
let siblings = document.querySelectorAll(NavDesktopDropdown.selector());
|
||||||
|
return Array.from(siblings).filter((sibling) => sibling !== this.accordion);
|
||||||
|
}
|
||||||
|
|
||||||
|
bindEvents() {
|
||||||
|
this.accordion.addEventListener("focus", () => {
|
||||||
|
this.open();
|
||||||
|
});
|
||||||
|
this.accordion.addEventListener("pointerenter", () => {
|
||||||
|
this.open();
|
||||||
|
});
|
||||||
|
this.accordion.addEventListener("blur", () => {
|
||||||
|
this.close();
|
||||||
|
});
|
||||||
|
this.accordion.addEventListener("pointerleave", () => {
|
||||||
|
this.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
open() {
|
||||||
|
super.open();
|
||||||
|
this.titleText.classList.add("large:tw-text-black");
|
||||||
|
this.accordion.classList.add("large:tw-border-black");
|
||||||
|
this.accordion.classList.remove("large:tw-border-transparent");
|
||||||
|
this.accordion.setAttribute("aria-selected", "true");
|
||||||
|
this.content.classList.add("large:tw-grid");
|
||||||
|
this.content.classList.remove("large:tw-hidden");
|
||||||
|
this.siblings = this.getSiblings();
|
||||||
|
this.siblings.forEach((sibling) => {
|
||||||
|
const titleText = sibling.querySelector("[data-accordion-title] h5");
|
||||||
|
titleText.classList.remove("large:tw-text-black");
|
||||||
|
titleText.classList.add("large:tw-text-gray-40");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
super.close();
|
||||||
|
this.titleText.classList.remove("large:tw-text-black");
|
||||||
|
this.accordion.classList.remove("large:tw-border-black");
|
||||||
|
this.accordion.classList.add("large:tw-border-transparent");
|
||||||
|
this.accordion.setAttribute("aria-selected", "false");
|
||||||
|
this.content.classList.remove("large:tw-grid");
|
||||||
|
this.content.classList.add("large:tw-hidden");
|
||||||
|
this.siblings = this.getSiblings();
|
||||||
|
this.siblings.forEach((sibling) => {
|
||||||
|
const titleText = sibling.querySelector("[data-accordion-title] h5");
|
||||||
|
titleText.classList.add("large:tw-text-black");
|
||||||
|
titleText.classList.remove("large:tw-text-gray-40");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NavDesktopDropdown;
|
|
@ -0,0 +1,39 @@
|
||||||
|
import Accordion from "../accordion/accordion";
|
||||||
|
|
||||||
|
class NavMobileDropdown extends Accordion {
|
||||||
|
static selector() {
|
||||||
|
return "[data-mobile-dropdown]";
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(node) {
|
||||||
|
super(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
bindEvents() {
|
||||||
|
super.bindEvents();
|
||||||
|
this.accordion.addEventListener("focus", () => {
|
||||||
|
this.addHoverEffects();
|
||||||
|
});
|
||||||
|
this.accordion.addEventListener("pointerenter", () => {
|
||||||
|
this.addHoverEffects();
|
||||||
|
});
|
||||||
|
this.accordion.addEventListener("blur", () => {
|
||||||
|
this.removeHoverEffects();
|
||||||
|
});
|
||||||
|
this.accordion.addEventListener("pointerleave", () => {
|
||||||
|
this.removeHoverEffects();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addHoverEffects() {
|
||||||
|
this.accordion.classList.add("tw-bg-blue-03");
|
||||||
|
this.titleText.classList.add("tw-underline");
|
||||||
|
}
|
||||||
|
|
||||||
|
removeHoverEffects() {
|
||||||
|
this.accordion.classList.remove("tw-bg-blue-03");
|
||||||
|
this.titleText.classList.remove("tw-underline");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NavMobileDropdown;
|
|
@ -38,6 +38,9 @@ import { initYoutubeRegretsAccordions } from "./foundation/pages/youtube-regrets
|
||||||
import { initYouTubeRegretsRecommendationsPieChart } from "./foundation/pages/youtube-regrets/recommendations-pie-chart";
|
import { initYouTubeRegretsRecommendationsPieChart } from "./foundation/pages/youtube-regrets/recommendations-pie-chart";
|
||||||
import { initYoutubeRegretsCarousel } from "./foundation/pages/youtube-regrets/carousel";
|
import { initYoutubeRegretsCarousel } from "./foundation/pages/youtube-regrets/carousel";
|
||||||
import { initYoutubeRegretsLocomotiveScroll } from "./foundation/pages/youtube-regrets/locomotive-scroll";
|
import { initYoutubeRegretsLocomotiveScroll } from "./foundation/pages/youtube-regrets/locomotive-scroll";
|
||||||
|
import Accordion from "./components/accordion/accordion.js";
|
||||||
|
import NavDesktopDropdown from "./components/nav/desktop-dropdown.js";
|
||||||
|
import NavMobileDropdown from "./components/nav/mobile-dropdown.js";
|
||||||
|
|
||||||
// Initializing component a11y browser console logging
|
// Initializing component a11y browser console logging
|
||||||
if (process.env.NODE_ENV === "development") {
|
if (process.env.NODE_ENV === "development") {
|
||||||
|
@ -53,6 +56,11 @@ let env, networkSiteURL;
|
||||||
// until all the React stuff is _actually_ done.
|
// until all the React stuff is _actually_ done.
|
||||||
const apps = [];
|
const apps = [];
|
||||||
|
|
||||||
|
function initComponent(ComponentClass) {
|
||||||
|
const items = document.querySelectorAll(ComponentClass.selector());
|
||||||
|
items.forEach((item) => new ComponentClass(item));
|
||||||
|
}
|
||||||
|
|
||||||
let main = {
|
let main = {
|
||||||
init() {
|
init() {
|
||||||
injectMultipageNav();
|
injectMultipageNav();
|
||||||
|
@ -62,6 +70,10 @@ let main = {
|
||||||
Dropdowns.init();
|
Dropdowns.init();
|
||||||
FoundationCarousels.init();
|
FoundationCarousels.init();
|
||||||
|
|
||||||
|
initComponent(Accordion);
|
||||||
|
initComponent(NavDesktopDropdown);
|
||||||
|
initComponent(NavMobileDropdown);
|
||||||
|
|
||||||
this.fetchEnv((envData) => {
|
this.fetchEnv((envData) => {
|
||||||
env = envData;
|
env = envData;
|
||||||
networkSiteURL = env.NETWORK_SITE_URL;
|
networkSiteURL = env.NETWORK_SITE_URL;
|
||||||
|
|
|
@ -54,11 +54,23 @@ let primaryNav = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setBodyHeight(openMenu) {
|
||||||
|
// set body height and overflow to prevent scrolling on the body when mobile nav is open
|
||||||
|
if (openMenu) {
|
||||||
|
document.body.style.height = `100vh`;
|
||||||
|
document.body.style.overflow = `hidden`;
|
||||||
|
} else {
|
||||||
|
document.body.style.height = `auto`;
|
||||||
|
document.body.style.overflow = `auto`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function setMenuState(openMenu) {
|
function setMenuState(openMenu) {
|
||||||
setWideMenuState(openMenu);
|
setWideMenuState(openMenu);
|
||||||
setNarrowMenuState(openMenu);
|
setNarrowMenuState(openMenu);
|
||||||
setBurgerState(openMenu);
|
setBurgerState(openMenu);
|
||||||
trackMenuState(openMenu);
|
trackMenuState(openMenu);
|
||||||
|
setBodyHeight(openMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener(`keyup`, (e) => {
|
document.addEventListener(`keyup`, (e) => {
|
||||||
|
|
|
@ -237,17 +237,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.narrow-screen-menu {
|
.narrow-screen-menu {
|
||||||
position: absolute;
|
position: fixed;
|
||||||
@apply tw-pt-32;
|
top: 65px;
|
||||||
|
bottom: 0;
|
||||||
@media (min-width: $nav-full-logo-breakpoint) {
|
|
||||||
padding-top: 72px;
|
|
||||||
}
|
|
||||||
|
|
||||||
height: 100vh;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
right: 0;
|
||||||
|
overflow-y: auto;
|
||||||
transition:
|
transition:
|
||||||
opacity 0.2s,
|
opacity 0.2s,
|
||||||
height 0s;
|
height 0s;
|
||||||
|
|
|
@ -17,6 +17,13 @@ module.exports = {
|
||||||
// eventually we have to extract what bootstrap base/reset styles we need
|
// eventually we have to extract what bootstrap base/reset styles we need
|
||||||
preflight: false,
|
preflight: false,
|
||||||
},
|
},
|
||||||
|
safelist: [
|
||||||
|
{
|
||||||
|
// Handle dynamic grid column sizing on templates (see fragments/blocks/nav/dropdown.html)
|
||||||
|
pattern: /w-(1|2|3|4)\/4/,
|
||||||
|
variants: ['large', 'hover', 'focus', 'large:hover', 'large:focus'],
|
||||||
|
},
|
||||||
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
plugin(function ({ addUtilities }) {
|
plugin(function ({ addUtilities }) {
|
||||||
// Adding Column Count to Tailwind CSS
|
// Adding Column Count to Tailwind CSS
|
||||||
|
@ -80,6 +87,9 @@ module.exports = {
|
||||||
gridAutoRows: {
|
gridAutoRows: {
|
||||||
"1fr": "1fr",
|
"1fr": "1fr",
|
||||||
},
|
},
|
||||||
|
borderWidth: {
|
||||||
|
'6': '6px',
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// Overriding default spacing
|
// Overriding default spacing
|
||||||
spacing: {
|
spacing: {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче