diff --git a/tbx/project_styleguide/templates/patterns/navigation/components/primary-nav-mobile.html b/tbx/project_styleguide/templates/patterns/navigation/components/primary-nav-mobile.html index 1ca129606..ad96cbd13 100644 --- a/tbx/project_styleguide/templates/patterns/navigation/components/primary-nav-mobile.html +++ b/tbx/project_styleguide/templates/patterns/navigation/components/primary-nav-mobile.html @@ -1,35 +1,16 @@ {% load wagtailcore_tags %} -{% comment %} -The `child_display` has 3 possible values: -- hide_children - do not show a subnavigation -- show_up_to_level1 - show level one child pages -- show_up_to_level2 - show level one and level two child pages -{% endcomment %} - {% for item in primarynav %} - {% with children=item.value.page.get_children.live.public.in_menu.specific child_display=item.value.child_display_behaviour %} -
  • - {% with link=item.value %} - - - {% if children and child_display != 'hide_children' %} - {% include "patterns/navigation/components/includes/subnav-menu-mobile.html" with links=children parent=link only %} - {% endif %} - {% endwith %} -
  • - {% endwith %} +
  • + {% with link=item.value %} + + {{ link.text }} + + {% endwith %} +
  • {% endfor %} + diff --git a/tbx/project_styleguide/templates/patterns/navigation/components/primary-nav-mobile.yaml b/tbx/project_styleguide/templates/patterns/navigation/components/primary-nav-mobile.yaml index 3af674c05..a2655d6e0 100644 --- a/tbx/project_styleguide/templates/patterns/navigation/components/primary-nav-mobile.yaml +++ b/tbx/project_styleguide/templates/patterns/navigation/components/primary-nav-mobile.yaml @@ -3,115 +3,25 @@ context: primarynav: - item: value: - child_display_behaviour: 'show_up_to_level2' text: Services url: '#' - page: - get_children: - live: - public: - in_menu: - specific: - - nav_text: Strategy and consultancy - get_children: - live: - public: - in_menu: - specific: - - nav_text: AI strategy - - nav_text: Content strategy and IA - - nav_text: Digital transformation - - nav_text: Innovation strategy - - nav_text: Product strategy - - nav_text: Service design - - nav_text: Technical architecture design - - nav_text: User research - - nav_text: Digital marketing - get_children: - live: - public: - in_menu: - specific: - - nav_text: Asset and campaign creative - - nav_text: Digital marketing training - - nav_text: Data and measurement - - nav_text: Digital marketing training - - nav_text: Email marketing - - nav_text: Google Ad Grants Management - - nav_text: Pay-per-click management - - nav_text: Search Engine Optimisation (SEO) - - nav_text: Social media management - - nav_text: Wagtail CMS services - get_children: - live: - public: - in_menu: - specific: - - nav_text: Developer support - - nav_text: Staff augmentation - - nav_text: Training and consultancy - - nav_text: Digital product development - item: value: - child_display_behaviour: 'show_up_to_level1' text: Sectors url: '#' - page: - get_children: - live: - public: - in_menu: - specific: - - nav_text: Charities - get_children: - live: - public: - in_menu: - specific: - - nav_text: Charity sub 1 - - nav_text: Charity sub 2 - - nav_text: Charity sub 2 - - nav_text: Higher Education - - nav_text: Government - item: value: - child_display_behaviour: 'show_up_to_level1' text: About url: '#' - page: - get_children: - live: - public: - in_menu: - specific: - - nav_text: Culture - get_children: - live: - public: - in_menu: - specific: - - nav_text: Culture child one - - nav_text: Culture child two - - nav_text: Culture child three - - nav_text: Jobs - get_children: - live: - public: - in_menu: - specific: - - nav_text: Jobs child one - - nav_text: Jobs child two - - nav_text: Jobs child three - item: value: - child_display_behaviour: 'hide-children' text: Thinking url: '#' - item: value: - child_display_behaviour: 'hide-children' text: Work url: '#' + tags: pageurl: 'link.url': diff --git a/tbx/project_styleguide/templates/patterns/navigation/components/primary-nav.html b/tbx/project_styleguide/templates/patterns/navigation/components/primary-nav.html index 8c37150cd..66b1b441d 100644 --- a/tbx/project_styleguide/templates/patterns/navigation/components/primary-nav.html +++ b/tbx/project_styleguide/templates/patterns/navigation/components/primary-nav.html @@ -1,43 +1,14 @@ {% load wagtailcore_tags %} -{% comment %} -The `child_display` has 3 possible values: -- hide_children - do not show a subnavigation -- show_up_to_level1 - show level one child pages -- show_up_to_level2 - show level one and level two child pages -{% endcomment %} - {% for item in primarynav %} - {% with children=item.value.page.get_children.live.public.in_menu.specific child_display=item.value.child_display_behaviour %} -
  • - {% with link=item.value %} - - {% if children and child_display == 'show_up_to_level1' %} - {# if we are only showing up to level 1, show a small dropdown #} - {% include "patterns/navigation/components/includes/subnav-menu-mini.html" with links=children last=forloop.last revcounter=forloop.revcounter only %} - {% elif children and child_display == 'show_up_to_level2' %} - {# if we are showing level 1 and level 2 children, show a wide dropdown #} - {% include "patterns/navigation/components/includes/subnav-menu.html" with links=children number=children|length only %} - {% endif %} - {% endwith %} -
  • - {% endwith %} +
  • + {% with link=item.value %} + + {{ link.text }} + + {% endwith %} +
  • {% endfor %} diff --git a/tbx/project_styleguide/templates/patterns/navigation/components/primary-nav.yaml b/tbx/project_styleguide/templates/patterns/navigation/components/primary-nav.yaml index 75f27fdaa..4b9755c22 100644 --- a/tbx/project_styleguide/templates/patterns/navigation/components/primary-nav.yaml +++ b/tbx/project_styleguide/templates/patterns/navigation/components/primary-nav.yaml @@ -1,117 +1,26 @@ context: - children: True primarynav: - item: value: - child_display_behaviour: 'show_up_to_level2' text: Services external_url: '#' - page: - get_children: - live: - public: - in_menu: - specific: - - nav_text: Strategy and consultancy - get_children: - live: - public: - in_menu: - specific: - - nav_text: AI strategy - - nav_text: Content strategy and IA - - nav_text: Digital transformation - - nav_text: Innovation strategy - - nav_text: Product strategy - - nav_text: Service design - - nav_text: Technical architecture design - - nav_text: User research - - nav_text: Digital marketing - get_children: - live: - public: - in_menu: - specific: - - nav_text: Asset and campaign creative - - nav_text: Digital marketing training - - nav_text: Data and measurement - - nav_text: Digital marketing training - - nav_text: Email marketing - - nav_text: Google Ad Grants Management - - nav_text: Pay-per-click management - - nav_text: Search Engine Optimisation (SEO) - - nav_text: Social media management - - nav_text: Wagtail CMS services - get_children: - live: - public: - in_menu: - specific: - - nav_text: Developer support - - nav_text: Staff augmentation - - nav_text: Training and consultancy - - nav_text: Digital product development - item: value: - child_display_behaviour: 'show_up_to_level1' text: Sectors external_url: '#' - page: - get_children: - live: - public: - in_menu: - specific: - - nav_text: Charities - get_children: - live: - public: - in_menu: - specific: - - nav_text: Charity sub 1 - - nav_text: Charity sub 2 - - nav_text: Charity sub 2 - - nav_text: Higher Education - - nav_text: Government - item: value: - child_display_behaviour: 'show_up_to_level1' text: About external_url: '#' - page: - get_children: - live: - public: - in_menu: - specific: - - nav_text: Culture - get_children: - live: - public: - in_menu: - specific: - - nav_text: Culture child one - - nav_text: Culture child two - - nav_text: Culture child three - - nav_text: Jobs - get_children: - live: - public: - in_menu: - specific: - - nav_text: Jobs child one - - nav_text: Jobs child two - - nav_text: Jobs child three - item: value: - child_display_behaviour: 'hide-children' text: Thinking external_link: '#' - item: value: - child_display_behaviour: 'hide-children' text: Work external_link: '#' + tags: pageurl: 'link.url': diff --git a/tbx/project_styleguide/templates/patterns/organisms/header/header.html b/tbx/project_styleguide/templates/patterns/organisms/header/header.html index 270571065..4e04b6787 100644 --- a/tbx/project_styleguide/templates/patterns/organisms/header/header.html +++ b/tbx/project_styleguide/templates/patterns/organisms/header/header.html @@ -1,43 +1,65 @@ {% load wagtailcore_tags wagtail_cache navigation_tags %} {% wagtail_site as current_site %} -
    - {% include "patterns/atoms/skip-link/skip-link.html" %} - -
    - {# Desktop navigation #} - +
    +
    + {% include "patterns/atoms/skip-link/skip-link.html" %} +
    + {# Primary desktop navigation #} + - {# Mode switcher desktop #} - {% include "patterns/molecules/mode_switcher/mode_switcher.html" %} -
    + {# Primary mobile menu toggle #} + - {# Mobile menu toggle #} -
    - Menu - -
    + {# Primary mobile navigation #} + - {# Mobile navigation #} - + {# Mode switcher desktop - hide for now #} + {% comment %} {% include "patterns/molecules/mode_switcher/mode_switcher.html" %} {% endcomment %} +
    + {# Mobile menu toggle - hide for now, will be reused in the secondary nav #} + {% comment %}
    + Menu + +
    + {# Mobile navigation #} + {% endcomment %} +
    diff --git a/tbx/project_styleguide/templates/patterns/styleguide/components/components.html b/tbx/project_styleguide/templates/patterns/styleguide/components/components.html index c46af4656..efeffc60a 100644 --- a/tbx/project_styleguide/templates/patterns/styleguide/components/components.html +++ b/tbx/project_styleguide/templates/patterns/styleguide/components/components.html @@ -6,7 +6,7 @@

    Mode switcher

    - {% include "patterns/molecules/mode_switcher/mode_switcher.html" %} +
    {% include "patterns/molecules/mode_switcher/mode_switcher.html" %}
    diff --git a/tbx/static_src/javascript/components/primary-mobile-menu.js b/tbx/static_src/javascript/components/primary-mobile-menu.js new file mode 100644 index 000000000..311d6fd75 --- /dev/null +++ b/tbx/static_src/javascript/components/primary-mobile-menu.js @@ -0,0 +1,84 @@ +class PrimaryMobileMenu { + static selector() { + return '[data-primary-mobile-menu-toggle]'; + } + + constructor(node) { + this.node = node; + this.body = document.querySelector('body'); + this.primaryMobileMenu = document.querySelector( + '[data-primary-mobile-menu]', + ); + this.lastMenuItem = document.querySelector( + '[data-last-menu-item-primary-mobile]', + ); + + this.state = { + open: false, + }; + + this.bindEventListeners(); + } + + bindEventListeners() { + this.node.addEventListener('click', () => { + this.open(); + }); + + // Close mobile dropdown with escape key for improved accessibility + document.addEventListener('keydown', (event) => { + if (event.key === 'Escape') { + if (this.state.open) { + this.close(); + this.state.open = false; + } + } + }); + + // Close mobile dropdown when clicking outside of the menu + document.addEventListener('click', (event) => { + if (this.state.open && !this.node.contains(event.target)) { + this.close(); + this.state.open = false; + } + }); + + // Close the mobile menu when the focus moves away from the last item in the top level + if (this.lastMenuItem === null) { + return; + } + + this.lastMenuItem.addEventListener('focusout', () => { + if (this.state.open) { + this.close(); + this.state.open = false; + } + }); + } + + open() { + // Fire a custom event which is useful if we need any other items such as + // a search box to close when the mobile menu opens + // Can be listened to with + // document.addEventListener('onMenuOpen', () => { + // // do stuff here...; + // }); + const menuOpenEvent = new Event('onMenuOpen'); + document.dispatchEvent(menuOpenEvent); + this.node.setAttribute('aria-expanded', 'true'); + this.body.classList.add('no-scroll'); + this.primaryMobileMenu.classList.add('is-visible'); + + this.state.open = true; + } + + close() { + this.node.setAttribute('aria-expanded', 'false'); + this.body.classList.remove('no-scroll'); + this.primaryMobileMenu.classList.remove('is-visible'); + + this.state.open = false; + } +} + +export default PrimaryMobileMenu; diff --git a/tbx/static_src/javascript/components/primary-mobile-menu.test.js b/tbx/static_src/javascript/components/primary-mobile-menu.test.js new file mode 100644 index 000000000..417009b8f --- /dev/null +++ b/tbx/static_src/javascript/components/primary-mobile-menu.test.js @@ -0,0 +1,58 @@ +import PrimaryMobileMenu from './primary-mobile-menu'; + +describe('MobileMenu', () => { + beforeEach(() => { + document.body.innerHTML = ` +