diff --git a/packages/styles/scss/components/masthead/_masthead.scss b/packages/styles/scss/components/masthead/_masthead.scss index eaed25489a7..8ad1a6e9050 100755 --- a/packages/styles/scss/components/masthead/_masthead.scss +++ b/packages/styles/scss/components/masthead/_masthead.scss @@ -1,5 +1,5 @@ /** - * Copyright IBM Corp. 2016, 2023 + * Copyright IBM Corp. 2016, 2024 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. @@ -270,6 +270,7 @@ :host(#{$c4d-prefix}-cloud-masthead-container) { position: relative; z-index: 900; + display: block; padding-block-start: $spacing-09; } diff --git a/packages/utilities/src/utilities/StickyHeader/StickyHeader.js b/packages/utilities/src/utilities/StickyHeader/StickyHeader.js index e68a9ccf700..5274b1d40f0 100644 --- a/packages/utilities/src/utilities/StickyHeader/StickyHeader.js +++ b/packages/utilities/src/utilities/StickyHeader/StickyHeader.js @@ -226,7 +226,7 @@ class StickyHeader { } const newY = window.scrollY; - this._lastScrollPosition = newY; + this._lastScrollPosition = Math.max(0, newY); /** * maxScrollaway is a calculated value matching the height of all components diff --git a/packages/web-components/src/components/masthead/masthead-composite.ts b/packages/web-components/src/components/masthead/masthead-composite.ts index eebad67d9fd..96cd65c04ed 100644 --- a/packages/web-components/src/components/masthead/masthead-composite.ts +++ b/packages/web-components/src/components/masthead/masthead-composite.ts @@ -8,7 +8,7 @@ */ import { LitElement, html, TemplateResult } from 'lit'; -import { state, property } from 'lit/decorators.js'; +import { state, property, query } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import ArrowRight16 from '../../internal/vendor/@carbon/web-components/icons/arrow--right/16.js'; import ifNonEmpty from '../../internal/vendor/@carbon/web-components/globals/directives/if-non-empty.js'; @@ -41,6 +41,7 @@ import { C4D_CUSTOM_PROFILE_LOGIN } from '../../globals/internal/feature-flags'; import C4DMastheadLogo from './masthead-logo'; import C4DMegaMenuTabs from './megamenu-tabs'; import C4DMegamenuTopNavMenu from './megamenu-top-nav-menu'; +import C4DMastheadL1 from './masthead-l1'; import './masthead'; import './masthead-button-cta'; import './masthead-l1'; @@ -94,6 +95,7 @@ export interface CMApp { version: string; ready: boolean; init: Function; + minimize: Function; refresh: Function; register: Function; deregister: Function; @@ -992,6 +994,9 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { // any previously opened megamenu. if (active && menuIndex !== undefined) { this._activeMegamenuIndex = menuIndex; + + // Close the Contact Module upon opening megamenu. + this.contactModuleApp?.minimize(); } // If clicking the same nav item to close megamenu, reset state to prune its @@ -1008,6 +1013,14 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { resolveFn(); }; + @HostListener(C4DMastheadL1.dropDownToggleEvent) + protected _handleL1DropdownToggle({ detail }: CustomEvent) { + const { isOpen } = detail; + if (isOpen) { + this.contactModuleApp?.minimize(); + } + } + /** * Sets the active megamenu tabpanel upon user interaction. * @@ -1325,6 +1338,47 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { : unauthenticatedCtaButtons; } + /** + * A reference to the c4d-masthead element. + */ + @query(`${c4dPrefix}-masthead`) + mastheadRef; + + /** + * Resize observer to trigger container height recalculations. + * + * @private + */ + private _heightResizeObserver = new ResizeObserver( + this._resizeObserverCallback.bind(this) + ); + + /** + * Prevents resize observer from blocking main thread. + */ + private _resizeObserverThrottle?: NodeJS.Timeout; + + /** + * Throttled callback for _heightResizeObserver. + */ + protected _resizeObserverCallback() { + clearTimeout(this._resizeObserverThrottle); + this._resizeObserverThrottle = setTimeout( + this._setContainerHeight.bind(this), + 100 + ); + } + + /** + * Sets root element's height equal to the height of the fixed masthead elements. + */ + protected _setContainerHeight() { + const { mastheadRef } = this; + if (mastheadRef) { + this.style.display = 'block'; + this.style.height = `${mastheadRef.getBoundingClientRect().height}px`; + } + } firstUpdated() { const { language, dataEndpoint } = this; globalInit(); @@ -1344,6 +1398,9 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { this._isMobileVersion = layoutBreakpoint.matches; this.requestUpdate(); }); + + // Keep render root's height in sync with c4d-masthead. + this._heightResizeObserver.observe(this.mastheadRef); } updated(changedProperties) { @@ -1359,6 +1416,11 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { } } + disconnectedCallback() { + super.disconnectedCallback(); + this._heightResizeObserver.disconnect(); + } + render() { const { _isMobileVersion: isMobileVersion, diff --git a/packages/web-components/src/components/masthead/masthead-contact.ts b/packages/web-components/src/components/masthead/masthead-contact.ts index d8073d81aa9..f37e399734c 100644 --- a/packages/web-components/src/components/masthead/masthead-contact.ts +++ b/packages/web-components/src/components/masthead/masthead-contact.ts @@ -12,10 +12,9 @@ import { property } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import Chat20 from '../../internal/vendor/@carbon/web-components/icons/chat/20.js'; import settings from '../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; +import HostListener from '../../internal/vendor/@carbon/web-components/globals/decorators/host-listener.js'; import styles from './masthead.scss'; import C4DMastheadProfile from './masthead-profile'; -import C4DMastheadContainer from './masthead-container'; -import { CMApp } from './masthead-composite'; import { carbonElement as customElement } from '../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element.js'; const { prefix, stablePrefix: c4dPrefix } = settings; @@ -33,6 +32,28 @@ class C4DMastheadContact extends C4DMastheadProfile { @property({ attribute: 'trigger-label' }) triggerLabel = 'Contact'; + /** + * Handles cm-app-pane-displayed event fired by CM_APP. + * + * @see DOCUMENT_EVENTS live-advisor/cm-app/js/helpers/otherConstants.js + * - https://github.ibm.com/live-advisor/cm-app/blob/master/js/helpers/otherConstants.js + */ + @HostListener('document:cm-app-pane-displayed') + protected _handleCMAppDisplayed = (_event: CustomEvent) => { + this.triggerLabel = 'Close contact window'; + }; + + /** + * Handles cm-app-pane-hidden event fired by CM_APP. + * + * @see DOCUMENT_EVENTS live-advisor/cm-app/js/helpers/otherConstants.js + * - https://github.ibm.com/live-advisor/cm-app/blob/master/js/helpers/otherConstants.js + */ + @HostListener('document:cm-app-pane-hidden') + protected _handleCMAppHidden = (_event: CustomEvent) => { + this.triggerLabel = 'Show contact window'; + }; + render() { const { triggerLabel, _handleClick: handleClick } = this; return html` @@ -46,25 +67,6 @@ class C4DMastheadContact extends C4DMastheadProfile { `; } - updated(changedProperties) { - if (changedProperties.has('expanded')) { - if (!this.expanded) { - const mastheadContainer = this.closest( - `${c4dPrefix}-masthead-container` - ) as C4DMastheadContainer; - - /** - * This is a workaround to minimize the chat module. Currently no minimize methods exist. - * - * @see https://github.ibm.com/live-advisor/cm-app - */ - if (mastheadContainer?.contactModuleApp) { - (mastheadContainer.contactModuleApp as CMApp).init(); - } - } - } - } - static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader } diff --git a/packages/web-components/src/components/masthead/masthead-container.ts b/packages/web-components/src/components/masthead/masthead-container.ts index 31857ae7a63..450e62c5e20 100644 --- a/packages/web-components/src/components/masthead/masthead-container.ts +++ b/packages/web-components/src/components/masthead/masthead-container.ts @@ -100,16 +100,17 @@ export function mapStateToProps( : translations?.[language]?.mastheadNav?.links, authenticatedProfileItems: !language ? undefined - : translations?.[language]?.profileMenu.signedin, + : translations?.[language]?.profileMenu?.signedin, unauthenticatedProfileItems: !language ? undefined - : translations?.[language]?.profileMenu.signedout, + : translations?.[language]?.profileMenu?.signedout, authenticatedCtaButtons: !language ? undefined - : translations?.[language]?.masthead?.profileMenu.signedin.ctaButtons, + : translations?.[language]?.masthead?.profileMenu?.signedin?.ctaButtons, unauthenticatedCtaButtons: !language ? undefined - : translations?.[language]?.masthead?.profileMenu.signedout.ctaButtons, + : translations?.[language]?.masthead?.profileMenu?.signedout + ?.ctaButtons, contactUsButton: !language ? undefined : translations?.[language]?.masthead?.contact, diff --git a/packages/web-components/src/components/masthead/masthead-l1.ts b/packages/web-components/src/components/masthead/masthead-l1.ts index 9f5a1baf155..7471e28597c 100644 --- a/packages/web-components/src/components/masthead/masthead-l1.ts +++ b/packages/web-components/src/components/masthead/masthead-l1.ts @@ -447,6 +447,7 @@ class C4DMastheadL1 extends StableSelectorMixin(LitElement) { ${title}${ChevronDown16()}