Skip to content

Commit

Permalink
feat(masthead): introduce active state of nav items (#4721)
Browse files Browse the repository at this point in the history
### Related Ticket(s)

Refs #4712.

### Changelog

**New**

- The active state for masthead nav items.
- `selected-menu-item` attribute to `<dds-masthead-composite>`.
  • Loading branch information
asudoh authored Dec 14, 2020
1 parent 56d542f commit de880d5
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 21 deletions.
1 change: 1 addition & 0 deletions packages/services-store/src/types/translateAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export interface MastheadL1 {

export interface MastheadL1Item {
title: string;
titleEnglish?: string;
url?: string;
menuItems?: MastheadL1Item[];
}
Expand Down
5 changes: 5 additions & 0 deletions packages/styles/scss/components/masthead/_masthead.scss
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,9 @@ $search-transition-timing: 95ms;
transition: left $transition--base motion(standard, productive);
}

:host(#{$dds-prefix}-top-nav-item),
:host(#{$dds-prefix}-top-nav-menu),
:host(#{$dds-prefix}-megamenu-top-nav-menu),
.#{$prefix}--header__nav {
a.#{$prefix}--header__menu-item {
@include masthead-top-nav-link;
Expand Down Expand Up @@ -303,7 +306,9 @@ $search-transition-timing: 95ms;
border-bottom: solid 3px $interactive-01;
}
}
}

.#{$prefix}--header__nav {
.#{$prefix}--header__menu-title[role='menuitem'][aria-expanded='true'] {
z-index: 0;
background-color: $ui-01;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,12 @@ class DDSDotcomShellComposite extends LitElement {
@property({ attribute: 'menu-button-assistive-text-inactive' })
menuButtonAssistiveTextInactive?: string;

/**
* The English title of the selected nav item.
*/
@property({ attribute: 'selected-menu-item' })
selectedMenuItem!: string;

/**
* `true` to open the locale modal. This goes to footer.
*/
Expand Down Expand Up @@ -284,6 +290,7 @@ class DDSDotcomShellComposite extends LitElement {
openLocaleModal,
openSearchDropdown,
navLinks,
selectedMenuItem,
userStatus,
_loadLangDisplay,
_setLanguage,
Expand All @@ -309,6 +316,7 @@ class DDSDotcomShellComposite extends LitElement {
language,
navLinks,
openSearchDropdown,
selectedMenuItem,
userStatus,
_loadSearchResults,
_loadTranslation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const StoryContent = () => html`
`;

export const Default = ({ parameters }) => {
const { brandName, userStatus, navLinks } = parameters?.props?.MastheadComposite ?? {};
const { brandName, selectedMenuItem, userStatus, navLinks } = parameters?.props?.MastheadComposite ?? {};
const { useMock } = parameters?.props?.Other ?? {};
return html`
<style>
Expand All @@ -89,6 +89,7 @@ export const Default = ({ parameters }) => {
? html`
<dds-masthead-composite
brand-name="${ifNonNull(brandName)}"
selected-menu-item="${ifNonNull(selectedMenuItem)}"
user-status="${ifNonNull(userStatus)}"
.authenticatedProfileItems="${ifNonNull(authenticatedProfileItems)}"
.navLinks="${navLinks}"
Expand All @@ -99,6 +100,7 @@ export const Default = ({ parameters }) => {
: html`
<dds-masthead-container
brand-name="${ifNonNull(brandName)}"
selected-menu-item="${ifNonNull(selectedMenuItem)}"
user-status="${ifNonNull(userStatus)}"
.navLinks="${navLinks}"
></dds-masthead-container>
Expand All @@ -108,7 +110,7 @@ export const Default = ({ parameters }) => {
};

export const withL1 = ({ parameters }) => {
const { brandName, userStatus, navLinks } = parameters?.props?.MastheadComposite ?? {};
const { brandName, selectedMenuItem, userStatus, navLinks } = parameters?.props?.MastheadComposite ?? {};
const { useMock } = parameters?.props?.Other ?? {};
return html`
<style>
Expand All @@ -118,6 +120,7 @@ export const withL1 = ({ parameters }) => {
? html`
<dds-masthead-composite
brand-name="${ifNonNull(brandName)}"
selected-menu-item="${ifNonNull(selectedMenuItem)}"
user-status="${ifNonNull(userStatus)}"
.authenticatedProfileItems="${ifNonNull(authenticatedProfileItems)}"
.l1Data="${l1Data}"
Expand All @@ -128,6 +131,7 @@ export const withL1 = ({ parameters }) => {
: html`
<dds-masthead-container
brand-name="${ifNonNull(brandName)}"
selected-menu-item="${ifNonNull(selectedMenuItem)}"
user-status="${ifNonNull(userStatus)}"
.l1Data="${l1Data}"
.navLinks="${navLinks}"
Expand All @@ -138,7 +142,7 @@ export const withL1 = ({ parameters }) => {
};

export const withAlternateLogoAndTooltip = ({ parameters }) => {
const { brandName, userStatus, navLinks } = parameters?.props?.MastheadComposite ?? {};
const { brandName, selectedMenuItem, userStatus, navLinks } = parameters?.props?.MastheadComposite ?? {};
const { useMock } = parameters?.props?.Other ?? {};
return html`
<style>
Expand All @@ -148,6 +152,7 @@ export const withAlternateLogoAndTooltip = ({ parameters }) => {
? html`
<dds-masthead-composite
brand-name="${ifNonNull(brandName)}"
selected-menu-item="${ifNonNull(selectedMenuItem)}"
user-status="${ifNonNull(userStatus)}"
.authenticatedProfileItems="${ifNonNull(authenticatedProfileItems)}"
.l1Data="${l1Data}"
Expand All @@ -159,6 +164,7 @@ export const withAlternateLogoAndTooltip = ({ parameters }) => {
: html`
<dds-masthead-container
brand-name="${ifNonNull(brandName)}"
selected-menu-item="${ifNonNull(selectedMenuItem)}"
user-status="${ifNonNull(userStatus)}"
.l1Data="${l1Data}"
.navLinks="${navLinks}"
Expand Down Expand Up @@ -190,6 +196,7 @@ export default {
knobs: {
MastheadComposite: ({ groupId }) => ({
brandName: textNullable('Brand name (brand-name)', '', groupId),
selectedMenuItem: textNullable('selected menu item (selected-menu-item)', 'Services & Consulting', groupId),
userStatus: select('The user authenticated status (user-status)', userStatuses, null, groupId),
logoHref: textNullable('Logo href (logo-href)', 'https://www.ibm.com', groupId),
}),
Expand Down
15 changes: 13 additions & 2 deletions packages/web-components/src/components/masthead/left-nav-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* LICENSE file in the root directory of this source tree.
*/

import { classMap } from 'lit-html/directives/class-map';
import { html, property, customElement, LitElement } from 'lit-element';
import ddsSettings from '@carbon/ibmdotcom-utilities/es/utilities/settings/settings.js';
import settings from 'carbon-components/es/globals/js/settings';
Expand Down Expand Up @@ -58,6 +59,12 @@ class DDSLeftNavMenu extends FocusMixin(LitElement) {
this._handleUserInitiatedToggle();
}

/**
* `true` if the menu should be in its active state.
*/
@property({ type: Boolean, reflect: true })
active = false;

/**
* The back button's text.
*/
Expand Down Expand Up @@ -87,13 +94,17 @@ class DDSLeftNavMenu extends FocusMixin(LitElement) {
}

render() {
const { backButtonText, expanded, title, _handleClickExpando: handleClickExpando } = this;
const { active, backButtonText, expanded, title, _handleClickExpando: handleClickExpando } = this;
const buttonClasses = classMap({
[`${prefix}--side-nav__submenu`]: true,
[`${prefix}--masthead__side-nav--submemu--selected`]: active,
});
return html`
<button
type="button"
aria-haspopup="true"
aria-expanded="${String(Boolean(expanded))}"
class="${prefix}--side-nav__submenu"
class="${buttonClasses}"
@click=${handleClickExpando}
>
<span class="${prefix}--side-nav__submenu-title">${title}</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,11 @@ class DDSMastheadComposite extends LitElement {
/**
* Renders the L1 Items
*
* @param target - defines the type of rendered item (top nav item / left nav item)
* @param options The options.
* @param [options.selectedMenuItem] The selected nav item.
* @param options.target The target of rendering navigation items.
*/
private _renderL1Items({ target }: { target: NAV_ITEMS_RENDER_TARGET }) {
private _renderL1Items({ selectedMenuItem, target }: { selectedMenuItem?: string; target: NAV_ITEMS_RENDER_TARGET }) {
if (!this.l1Data) return undefined;
const { menuItems } = this.l1Data;
if (menuItems) {
Expand All @@ -93,6 +95,7 @@ class DDSMastheadComposite extends LitElement {
return elem.menuItems
? html`
<dds-top-nav-menu
?active="${selectedMenuItem && elem.titleEnglish === selectedMenuItem}"
menu-label="${elem.title}"
trigger-content="${elem.title}"
data-autoid="${ddsPrefix}--masthead__l1-nav--nav-${i}"
Expand All @@ -110,6 +113,7 @@ class DDSMastheadComposite extends LitElement {
`
: html`
<dds-top-nav-item
?active="${selectedMenuItem && elem.titleEnglish === selectedMenuItem}"
href="${elem.url}"
title="${elem.title}"
data-autoid="${ddsPrefix}--masthead__l1-nav--nav-${i}"
Expand All @@ -121,7 +125,11 @@ class DDSMastheadComposite extends LitElement {
: menuItems.map((elem: MastheadL1Item, i) =>
elem.menuItems
? html`
<dds-left-nav-menu title="${elem.title}" data-autoid="${ddsPrefix}--masthead__l1-sidenav--nav-${i}">
<dds-left-nav-menu
?active="${selectedMenuItem && elem.titleEnglish === selectedMenuItem}"
title="${elem.title}"
data-autoid="${ddsPrefix}--masthead__l1-sidenav--nav-${i}"
>
${elem.menuItems.map(
(item, j) => html`
<dds-left-nav-menu-item
Expand All @@ -135,6 +143,7 @@ class DDSMastheadComposite extends LitElement {
`
: html`
<dds-left-nav-item
?active="${selectedMenuItem && elem.titleEnglish === selectedMenuItem}"
href="${elem.url}"
title="${elem.title}"
data-autoid="${ddsPrefix}--masthead__l1-sidenav--nav-${i}"
Expand All @@ -149,8 +158,11 @@ class DDSMastheadComposite extends LitElement {
/**
* Renders L1 menu based on l1Data
*
* @param [options] The options.
* @param [options.selectedMenuItem] The selected nav item.
* @returns The L1 nav.
*/
private _renderL1() {
private _renderL1({ selectedMenuItem }: { selectedMenuItem?: string } = {}) {
if (!this.l1Data) return undefined;
const { url, title } = this.l1Data;
return html`
Expand All @@ -160,7 +172,7 @@ class DDSMastheadComposite extends LitElement {
: html`
<dds-masthead-l1-name title="${title}" url="${url}"></dds-masthead-l1-name>
`}
${this._renderL1Items({ target: NAV_ITEMS_RENDER_TARGET.TOP_NAV })}
${this._renderL1Items({ selectedMenuItem, target: NAV_ITEMS_RENDER_TARGET.TOP_NAV })}
</dds-masthead-l1>
`;
}
Expand Down Expand Up @@ -292,15 +304,16 @@ class DDSMastheadComposite extends LitElement {

/**
* @param options The options.
* @param [options.selectedMenuItem] The selected nav item.
* @param options.target The target of rendering navigation items.
* @returns The nav items.
*/
private _renderNavItems({ target }: { target: NAV_ITEMS_RENDER_TARGET }) {
private _renderNavItems({ selectedMenuItem, target }: { selectedMenuItem?: string; target: NAV_ITEMS_RENDER_TARGET }) {
const { navLinks } = this;
return !navLinks
? undefined
: navLinks.map((link, i) => {
const { menuSections = [], title, url } = link;
const { menuSections = [], title, titleEnglish, url } = link;
let sections;
let mobileSections;
if (link.hasMegapanel) {
Expand Down Expand Up @@ -332,6 +345,7 @@ class DDSMastheadComposite extends LitElement {
if (sections.length === 0) {
return html`
<dds-top-nav-item
?active="${selectedMenuItem && titleEnglish === selectedMenuItem}"
href="${url}"
title="${title}"
data-autoid="${ddsPrefix}--masthead__l0-nav--nav-${i}"
Expand All @@ -341,6 +355,7 @@ class DDSMastheadComposite extends LitElement {
if (link.hasMegapanel) {
return html`
<dds-megamenu-top-nav-menu
?active="${selectedMenuItem && titleEnglish === selectedMenuItem}"
menu-label="${title}"
trigger-content="${title}"
data-autoid="${ddsPrefix}--masthead__l0-nav--nav-${i}"
Expand All @@ -351,6 +366,7 @@ class DDSMastheadComposite extends LitElement {
}
return html`
<dds-top-nav-menu
?active="${selectedMenuItem && titleEnglish === selectedMenuItem}"
menu-label="${title}"
trigger-content="${title}"
data-autoid="${ddsPrefix}--masthead__l0-nav--nav-${i}"
Expand All @@ -362,13 +378,18 @@ class DDSMastheadComposite extends LitElement {
return sections.length === 0
? html`
<dds-left-nav-item
?active="${selectedMenuItem && titleEnglish === selectedMenuItem}"
href="${url}"
title="${title}"
data-autoid="${ddsPrefix}--masthead__l0-sidenav--nav-${i}"
></dds-left-nav-item>
`
: html`
<dds-left-nav-menu title="${title}" data-autoid="${ddsPrefix}--masthead__l0-sidenav--nav-${i}">
<dds-left-nav-menu
?active="${selectedMenuItem && titleEnglish === selectedMenuItem}"
title="${title}"
data-autoid="${ddsPrefix}--masthead__l0-sidenav--nav-${i}"
>
${mobileSections}
</dds-left-nav-menu>
`;
Expand Down Expand Up @@ -451,6 +472,12 @@ class DDSMastheadComposite extends LitElement {
@property({ attribute: 'menu-button-assistive-text-inactive' })
menuButtonAssistiveTextInactive!: string;

/**
* The English title of the selected nav item.
*/
@property({ attribute: 'selected-menu-item' })
selectedMenuItem!: string;

/**
* The profile items for unauthenticated state.
*/
Expand Down Expand Up @@ -543,6 +570,7 @@ class DDSMastheadComposite extends LitElement {
language,
openSearchDropdown,
searchPlaceholder,
selectedMenuItem,
unauthenticatedProfileItems,
userStatus,
l1Data,
Expand All @@ -558,8 +586,8 @@ class DDSMastheadComposite extends LitElement {
: html`
<dds-left-nav-name>${brandName}</dds-left-nav-name>
`}
${l1Data ? undefined : this._renderNavItems({ target: NAV_ITEMS_RENDER_TARGET.LEFT_NAV })}
${l1Data ? this._renderL1Items({ target: NAV_ITEMS_RENDER_TARGET.LEFT_NAV }) : undefined}
${l1Data ? undefined : this._renderNavItems({ selectedMenuItem, target: NAV_ITEMS_RENDER_TARGET.LEFT_NAV })}
${l1Data ? this._renderL1Items({ selectedMenuItem, target: NAV_ITEMS_RENDER_TARGET.LEFT_NAV }) : undefined}
</dds-left-nav>
<dds-masthead aria-label="${ifNonNull(mastheadAssistiveText)}">
<dds-masthead-menu-button
Expand All @@ -578,7 +606,7 @@ class DDSMastheadComposite extends LitElement {
? undefined
: html`
<dds-top-nav menu-bar-label="${ifNonNull(menuBarAssistiveText)}">
${this._renderNavItems({ target: NAV_ITEMS_RENDER_TARGET.TOP_NAV })}
${this._renderNavItems({ selectedMenuItem, target: NAV_ITEMS_RENDER_TARGET.TOP_NAV })}
</dds-top-nav>
`}
<dds-masthead-search-composite
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@
fill: $text-01;
}

a.#{$prefix}--header__menu-item[role='menuitem'] {
a.#{$prefix}--header__menu-item {
@include masthead-top-nav-link;

&:hover {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
import { customElement } from 'lit-element';
import settings from 'carbon-components/es/globals/js/settings';
import ddsSettings from '@carbon/ibmdotcom-utilities/es/utilities/settings/settings.js';
import BXHeaderMenu from 'carbon-web-components/es/components/ui-shell/header-menu.js';
import { forEach } from '../../globals/internal/collection-helpers';
import DDSTopNavMenu from './top-nav-menu';
import DDSMegaMenuOverlay from './megamenu-overlay';
import styles from './masthead.scss';

Expand All @@ -24,7 +24,7 @@ const { stablePrefix: ddsPrefix } = ddsSettings;
* @element dds-megamenu-top-nav-menu
*/
@customElement(`${ddsPrefix}-megamenu-top-nav-menu`)
class DDSMegaMenuTopNavMenu extends BXHeaderMenu {
class DDSMegaMenuTopNavMenu extends DDSTopNavMenu {
/**
* The observer for the resize of the viewport.
*/
Expand Down Expand Up @@ -75,6 +75,7 @@ class DDSMegaMenuTopNavMenu extends BXHeaderMenu {
}

updated(changedProperties) {
super.updated(changedProperties);
if (changedProperties.has('expanded')) {
const doc = this.getRootNode() as Document;
forEach(doc.querySelectorAll((this.constructor as typeof DDSMegaMenuTopNavMenu).selectorOverlay), item => {
Expand Down
Loading

0 comments on commit de880d5

Please sign in to comment.