From 905dd99100ecb68beb6479e2fcaca8844a20d147 Mon Sep 17 00:00:00 2001 From: Joshua Fernandes <83997348+joshua-salsadigital@users.noreply.github.com> Date: Mon, 18 Mar 2024 14:32:21 +0530 Subject: [PATCH] Refactored Navigation component to use `type` instead of `dropdown` prop. (#113) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Joshua Fernandes <“joshua.1234511@yahoo.in”> --- components/00-base/_variables.components.scss | 4 + components/00-base/collapsible/collapsible.js | 4 +- components/03-organisms/header/header.scss | 138 +++++++++++- .../03-organisms/header/header.stories.twig | 4 +- .../03-organisms/navigation/navigation.scss | 200 +++--------------- .../navigation/navigation.stories.js | 5 +- .../03-organisms/navigation/navigation.twig | 8 +- 7 files changed, 186 insertions(+), 177 deletions(-) diff --git a/components/00-base/_variables.components.scss b/components/00-base/_variables.components.scss index 379d2ca5..2cc3a4ff 100644 --- a/components/00-base/_variables.components.scss +++ b/components/00-base/_variables.components.scss @@ -930,6 +930,10 @@ $ct-message-dark-warning-icon-color: $ct-message-dark-warning-color !default; // // Navigation can be rendered in 3 ways: plain, with dropdown and with drawer. +// Inline. +$ct-navigation-inline-column-gutter: $ct-item-list-horizontal-regular-column-gap !default; +$ct-navigation-inline-row-gutter: $ct-item-list-horizontal-regular-column-gap !default; + // Dropdown. $ct-navigation-dropdown-zindex: 11 !default; $ct-navigation-dropdown-border-radius: $ct-border-radius !default; diff --git a/components/00-base/collapsible/collapsible.js b/components/00-base/collapsible/collapsible.js index 27d2a7f4..5adee974 100644 --- a/components/00-base/collapsible/collapsible.js +++ b/components/00-base/collapsible/collapsible.js @@ -226,7 +226,7 @@ CivicThemeCollapsible.prototype.closeGroup = function (group) { // eslint-disable-next-line prefer-template document.querySelectorAll('[data-collapsible-group=' + group + ']:not([data-collapsible-collapsed])').forEach((el) => { if (el !== currentEl) { - el.dispatchEvent(new CustomEvent('ct.collapsible.collapse', { bubbles: true })); + el.dispatchEvent(new CustomEvent('ct.collapsible.collapse', { bubbles: true, detail: { closeGroup: true } })); } }); } @@ -255,7 +255,7 @@ CivicThemeCollapsible.prototype.collapse = function (animate, evt) { } if (evt && evt.target) { - if (evt.detail.keydown) { + if (evt.detail.keydown && !evt.detail.closeGroup) { if (evt.target.closest('[data-collapsible="true"]') !== t.el) { return; } diff --git a/components/03-organisms/header/header.scss b/components/03-organisms/header/header.scss index 864f15cb..30d4ccc7 100644 --- a/components/03-organisms/header/header.scss +++ b/components/03-organisms/header/header.scss @@ -5,10 +5,38 @@ .ct-header { $root: &; - &__content-top2, + &__content-top2 { + margin-top: ct-spacing(); + margin-bottom: ct-spacing(); + } + &__content-top3 { margin-top: ct-spacing(); margin-bottom: ct-spacing(); + + .ct-navigation { + $root-dropdown: '.ct-navigation'; + &#{$root-dropdown}--dropdown { + #{$root-dropdown}__items { + #{$root-dropdown}__menu { + .ct-menu__item { + // Links - level 0. + &--level-0 { + margin-right: ct-spacing(2); + + &:last-child { + margin-right: 0; + } + + > .ct-link { + text-align: center; + } + } + } + } + } + } + } } &__middle { @@ -34,6 +62,114 @@ display: flex; justify-content: flex-end; } + + .ct-navigation { + $root-drawer: '.ct-navigation'; + + &#{$root-drawer}--drawer { + #{$root-drawer}__items { + #{$root-drawer}__menu { + .ct-menu__item { + // Links - level 0. + &--level-0 { + border-bottom: solid ct-particle(0.5); + + > .ct-link { + display: block; + padding: ct-spacing(2); + text-align: center; + + &::after { + right: ct-spacing(); + margin-top: -1 * ct-particle(0.25); + top: ct-spacing(2); + } + } + } + } + } + } + + @include ct-component-theme($root-drawer) using($root-drawer, $theme) { + #{$root-drawer}__items { + #{$root-drawer}__menu { + .ct-menu__item { + // Links - level 0. + &--level-0 { + border-bottom-color: ct-component-var($root-drawer, $theme, drawer-menu-item, border-color); + + &:hover { + @include ct-component-property($root-drawer, $theme, drawer-menu-item, hover, background-color); + + border-bottom-color: ct-component-var($root-drawer, $theme, drawer-menu-item, hover, border-color); + } + + &:active { + @include ct-component-property($root-drawer, $theme, drawer-menu-item, active, background-color); + + border-bottom-color: ct-component-var($root-drawer, $theme, drawer-menu-item, active, border-color); + } + + &[data-collapsible] { + @if $theme == 'light' { + color: $ct-navigation-light-drawer-color; + } + @else { + color: $ct-navigation-dark-drawer-color; + } + + border-bottom-color: ct-component-var($root-drawer, $theme, drawer, border-color); + + &:hover { + @if $theme == 'light' { + color: $ct-navigation-light-drawer-hover-color; + } + @else { + color: $ct-navigation-dark-drawer-hover-color; + } + + @include ct-component-property($root-drawer, $theme, drawer-menu-item, hover, background-color); + + border-bottom-color: ct-component-var($root-drawer, $theme, drawer-menu-item, hover, border-color); + } + + &:active { + @include ct-component-property($root-drawer, $theme, drawer-menu-item, active, background-color); + + border-bottom-color: ct-component-var($root-drawer, $theme, drawer-menu-item, active, border-color); + } + } + + &[data-collapsible-collapsed] { + border-bottom-color: ct-component-var($root-drawer, $theme, drawer-menu-item, border-color); + } + + &.ct-menu__item--active-trail { + border-bottom-color: ct-component-var($root-drawer, $theme, drawer, border-color); + } + + > .ct-link { + @include ct-component-property($root-drawer, $theme, drawer-menu-item, background-color); + @include ct-component-property($root-drawer, $theme, drawer, color); + + &:hover { + @include ct-component-property($root-drawer, $theme, drawer-menu-item, hover, background-color); + @include ct-component-property($root-drawer, $theme, drawer, hover, color); + } + + &[aria-expanded='true'], + &:active { + @include ct-component-property($root-drawer, $theme, drawer-menu-item, active, background-color); + @include ct-component-property($root-drawer, $theme, drawer, active, color); + } + } + } + } + } + } + } + } + } } .ct-mobile-navigation-trigger { diff --git a/components/03-organisms/header/header.stories.twig b/components/03-organisms/header/header.stories.twig index 7b20e7e6..f8ba26f1 100644 --- a/components/03-organisms/header/header.stories.twig +++ b/components/03-organisms/header/header.stories.twig @@ -21,7 +21,7 @@ {% include '@organisms/navigation/navigation.twig' with { theme: theme, items: secondary_navigation_items, - dropdown: 'dropdown', + type: 'dropdown', modifier_class: 'ct-justify-content-end', } only %} {% endset %} @@ -39,7 +39,7 @@ {% include '@organisms/navigation/navigation.twig' with { theme: theme, items: primary_navigation_items, - dropdown: 'drawer', + type: 'drawer', dropdown_columns: primary_navigation_dropdown_columns, dropdown_columns_fill: primary_navigation_dropdown_columns_fill, modifier_class: 'ct-justify-content-end', diff --git a/components/03-organisms/navigation/navigation.scss b/components/03-organisms/navigation/navigation.scss index 84e51c4e..0897ee80 100644 --- a/components/03-organisms/navigation/navigation.scss +++ b/components/03-organisms/navigation/navigation.scss @@ -18,14 +18,6 @@ &#{$root}--none { #{$root}__items { - display: none; - align-items: center; - height: 100%; - - @include ct-breakpoint($ct-navigation-breakpoint) { - display: flex; - } - #{$root}__menu { &.ct-menu, .ct-menu { @@ -36,70 +28,53 @@ margin: 0; } - // First-level items to be displayed inline. - &.ct-menu--level-0 { - display: flex; + .ct-menu__sub-menu { + margin-top: ct-spacing(2); } .ct-menu__item { - // Links - level 0. - &--level-0 { - border-bottom: solid ct-particle(0.5); + margin-bottom: ct-spacing(2); + margin-left: ct-spacing(2); + } - > .ct-link { - display: block; - padding: ct-spacing(2); - text-align: center; - - &::after { - right: ct-spacing(); - margin-top: -1 * ct-particle(0.25); - top: ct-spacing(2); - } - } - } + &.ct-menu > .ct-menu__item { + margin-left: 0; } } } + } - @include ct-component-theme($root) using($root, $theme) { - #{$root}__items { - .ct-menu__item { - // Links - level 0. - &--level-0 { - border-bottom-color: ct-component-var($root, $theme, menu-item, border-color); - - &:hover { - @include ct-component-property($root, $theme, menu-item, hover, background-color); - - border-bottom-color: ct-component-var($root, $theme, menu-item, hover, border-color); - } - - &:active { - @include ct-component-property($root, $theme, menu-item, active, background-color); + &#{$root}--inline { + #{$root}__items { + #{$root}__menu { + // First-level items to be displayed inline. + &.ct-menu--level-0 { + display: flex; + column-gap: $ct-navigation-inline-column-gutter; + row-gap: $ct-navigation-inline-row-gutter; + flex-wrap: wrap; + } - border-bottom-color: ct-component-var($root, $theme, menu-item, active, border-color); - } + &.ct-menu, + .ct-menu { + @include ct-print-hide(); - &.ct-menu__item--active-trail { - border-bottom-color: ct-component-var($root, $theme, menu, border-color); - } + list-style: none; + padding: 0; + margin: 0; + } - > .ct-link { - @include ct-component-property($root, $theme, menu-item, background-color); - @include ct-component-property($root, $theme, menu, color); + .ct-menu__sub-menu { + margin-top: ct-spacing(2); + } - &:hover { - @include ct-component-property($root, $theme, menu-item, hover, background-color); - @include ct-component-property($root, $theme, menu, hover, color); - } + .ct-menu__item { + margin-bottom: ct-spacing(2); + margin-left: ct-spacing(2); + } - &:active { - @include ct-component-property($root, $theme, menu-item, active, background-color); - @include ct-component-property($root, $theme, menu, active, color); - } - } - } + &.ct-menu > .ct-menu__item { + margin-left: 0; } } } @@ -130,25 +105,6 @@ // First-level items to be displayed inline. display: flex; } - - .ct-menu__item { - // Links - level 0. - &--level-0 { - border-bottom: solid ct-particle(0.5); - - > .ct-link { - display: block; - padding: ct-spacing(2); - text-align: center; - - &::after { - right: ct-spacing(); - margin-top: -1 * ct-particle(0.25); - top: ct-spacing(2); - } - } - } - } } // Menu item with dropdown. @@ -271,81 +227,6 @@ @include ct-component-theme($root) using($root, $theme) { #{$root}__items { - #{$root}__menu { - .ct-menu__item { - // Links - level 0. - &--level-0 { - border-bottom-color: ct-component-var($root, $theme, drawer-menu-item, border-color); - - &:hover { - @include ct-component-property($root, $theme, drawer-menu-item, hover, background-color); - - border-bottom-color: ct-component-var($root, $theme, drawer-menu-item, hover, border-color); - } - - &:active { - @include ct-component-property($root, $theme, drawer-menu-item, active, background-color); - - border-bottom-color: ct-component-var($root, $theme, drawer-menu-item, active, border-color); - } - - &[data-collapsible] { - @if $theme == 'light' { - color: $ct-navigation-light-drawer-color; - } - @else { - color: $ct-navigation-dark-drawer-color; - } - - border-bottom-color: ct-component-var($root, $theme, drawer, border-color); - - &:hover { - @if $theme == 'light' { - color: $ct-navigation-light-drawer-hover-color; - } - @else { - color: $ct-navigation-dark-drawer-hover-color; - } - - @include ct-component-property($root, $theme, drawer-menu-item, hover, background-color); - - border-bottom-color: ct-component-var($root, $theme, drawer-menu-item, hover, border-color); - } - - &:active { - @include ct-component-property($root, $theme, drawer-menu-item, active, background-color); - - border-bottom-color: ct-component-var($root, $theme, drawer-menu-item, active, border-color); - } - } - - &[data-collapsible-collapsed] { - border-bottom-color: ct-component-var($root, $theme, drawer-menu-item, border-color); - } - - &.ct-menu__item--active-trail { - border-bottom-color: ct-component-var($root, $theme, drawer, border-color); - } - - > .ct-link { - @include ct-component-property($root, $theme, drawer-menu-item, background-color); - @include ct-component-property($root, $theme, drawer, color); - - &:hover { - @include ct-component-property($root, $theme, drawer-menu-item, hover, background-color); - @include ct-component-property($root, $theme, drawer, hover, color); - } - - &[aria-expanded='true'], - &:active { - @include ct-component-property($root, $theme, drawer-menu-item, active, background-color); - @include ct-component-property($root, $theme, drawer, active, color); - } - } - } - } - } - #{$root}__has-dropdown { .ct-menu__sub-menu__wrapper--level-1 { @include ct-component-property($root, $theme, drawer-sub-menu, background-color); @@ -436,19 +317,6 @@ display: block; } - // Links - level 0. - &--level-0 { - margin-right: ct-spacing(2); - - &:last-child { - margin-right: 0; - } - - > .ct-link { - text-align: center; - } - } - > .ct-link { &::after { right: ct-spacing(); diff --git a/components/03-organisms/navigation/navigation.stories.js b/components/03-organisms/navigation/navigation.stories.js index dbd1cb2f..c71c5b8d 100644 --- a/components/03-organisms/navigation/navigation.stories.js +++ b/components/03-organisms/navigation/navigation.stories.js @@ -24,10 +24,11 @@ export const Navigation = (knobTab) => { generalKnobTab, ), title: text('Title', 'Navigation title', generalKnobTab), - dropdown: radios( - 'Dropdown', + type: radios( + 'Type', { None: 'none', + Inline: 'inline', Dropdown: 'dropdown', Drawer: 'drawer', }, diff --git a/components/03-organisms/navigation/navigation.twig b/components/03-organisms/navigation/navigation.twig index 5c547b21..996afb0c 100644 --- a/components/03-organisms/navigation/navigation.twig +++ b/components/03-organisms/navigation/navigation.twig @@ -7,7 +7,7 @@ * - theme: [string] Theme: light, dark. * - items: [array] Array of menu items. * - title: [string] Navigation title. - * - dropdown: [string] One of: none, dropdown, drawer. + * - type: [string] One of: none, inline, dropdown, drawer. * - dropdown_columns: [integer] Number of columns in the dropdown drawer. * - dropdown_columns_fill: [bollean] Fill columns. * - is_animated: [bollean] Use animation for transitions. @@ -18,18 +18,18 @@ #} {% set menu_id = menu_id|default('navigation') %} -{% set dropdown_class = 'ct-navigation--%s'|format(dropdown|default('none')) %} +{% set dropdown_class = 'ct-navigation--%s'|format(type|default('none')) %} {% set theme_class = 'ct-theme-%s'|format(theme|default('light')) %} {% set modifier_class = '%s %s %s'|format(theme_class, dropdown_class, modifier_class|default('')) %} {% if items is not empty %} - {% if dropdown in ['dropdown', 'drawer'] %} + {% if type in ['dropdown', 'drawer'] %} {% for key in items|keys %} {% if items[key].below %} {# Item attributes to convert them into a collapsible element. #} {% set item_attributes = 'data-collapsible data-collapsible-collapsed data-collapsible-group=' ~ menu_id ~ ' ' ~ (is_animated ? 'data-collapsible-duration=250' : 'data-collapsible-duration=0') %} - {% if dropdown == 'drawer' %} + {% if type == 'drawer' %} {# Item classes to style dynamically. #} {% set item_dropdown_columns_class = dropdown_columns ? 'ct-navigation__dropdown-columns--%s'|format(dropdown_columns) : '' %} {% set item_dropdown_columns_fill_class = dropdown_columns_fill ? 'ct-navigation__dropdown-columns--fill' : '' %}