diff --git a/packages/carbon-web-components/src/components/tooltip/tooltip.ts b/packages/carbon-web-components/src/components/tooltip/tooltip.ts index 209aed62203..0f5e0e14096 100644 --- a/packages/carbon-web-components/src/components/tooltip/tooltip.ts +++ b/packages/carbon-web-components/src/components/tooltip/tooltip.ts @@ -67,6 +67,12 @@ class CDSTooltip extends HostListenerMixin(CDSPopover) { @property({ reflect: true }) size = false; + /** + * Specify the timeout reference for the tooltip + */ + @property({ reflect: true }) + timeoutId = 0; + /** * Specify whether the tooltip should be open when it first renders */ @@ -77,7 +83,8 @@ class CDSTooltip extends HostListenerMixin(CDSPopover) { * Handles `mouseover` event on this element. */ private _handleHover = async () => { - setTimeout(async () => { + window.clearTimeout(this.timeoutId); + this.timeoutId = window.setTimeout(async () => { this.open = true; const { open, updateComplete } = this; if (open) { @@ -93,7 +100,8 @@ class CDSTooltip extends HostListenerMixin(CDSPopover) { * Handles `mouseleave` event on this element. */ private _handleHoverOut = async () => { - setTimeout(async () => { + window.clearTimeout(this.timeoutId); + this.timeoutId = window.setTimeout(async () => { const { open } = this; if (open) { this.open = false; diff --git a/packages/services-store/src/actions/__tests__/translateAPI.test.ts b/packages/services-store/src/actions/__tests__/translateAPI.test.ts index bd875da1eff..1cf6c65188e 100644 --- a/packages/services-store/src/actions/__tests__/translateAPI.test.ts +++ b/packages/services-store/src/actions/__tests__/translateAPI.test.ts @@ -38,14 +38,10 @@ const mockTranslation: Partial = { }, { title: 'menu-title-foo', - menuSections: [ + submenu: [ { - menuItems: [ - { - title: 'menu-item-title-bar', - url: 'https://carbon-design-system.github.io/carbon-for-ibm-dotcom/canary/web-components/bar', - }, - ], + title: 'menu-item-title-bar', + url: 'https://carbon-design-system.github.io/carbon-for-ibm-dotcom/canary/web-components/bar', }, ], }, @@ -54,7 +50,7 @@ const mockTranslation: Partial = { }; const endpoint = - '/common/carbon-for-ibm-dotcom/translations/masthead-footer/v2'; + '/common/carbon-for-ibm-dotcom/translations/masthead-footer/v2.1'; describe('Redux actions for `TranslateAPI`', () => { it('dispatches the action to set translation data', () => { diff --git a/packages/services-store/src/reducers/__tests__/translateAPI.test.ts b/packages/services-store/src/reducers/__tests__/translateAPI.test.ts index af002cd8dad..2ed09bd7758 100644 --- a/packages/services-store/src/reducers/__tests__/translateAPI.test.ts +++ b/packages/services-store/src/reducers/__tests__/translateAPI.test.ts @@ -25,14 +25,10 @@ const mockTranslation: Partial = { }, { title: 'menu-title-foo', - menuSections: [ + submenu: [ { - menuItems: [ - { - title: 'menu-item-title-bar', - url: 'https://carbon-design-system.github.io/carbon-for-ibm-dotcom/canary/web-components/bar', - }, - ], + title: 'menu-item-title-bar', + url: 'https://carbon-design-system.github.io/carbon-for-ibm-dotcom/canary/web-components/bar', }, ], }, diff --git a/packages/services-store/src/types/translateAPI.ts b/packages/services-store/src/types/translateAPI.ts index b9884009b36..aa2d31d9b5f 100644 --- a/packages/services-store/src/types/translateAPI.ts +++ b/packages/services-store/src/types/translateAPI.ts @@ -1,7 +1,7 @@ /** * @license * - * Copyright IBM Corp. 2020, 2023 + * Copyright IBM Corp. 2020, 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. @@ -29,69 +29,29 @@ export interface BasicLinkSet { links: BasicLink[]; } -/** - * A feature in mega panel. - */ -export interface MegapanelFeature { - heading?: string; - imageUrl?: string; - linkTitle?: string; - linkUrl?: string; -} - -/** - * A content in mega panel. - */ -export interface MegapanelContent { - headingTitle?: string; - headingUrl?: string; - description?: string; - quickLinks: BasicLinkSet; - feature: MegapanelFeature; +export interface L0Menu { + items: L0MenuItem[]; } -/** - * A menu item in masthead. - */ -export interface MastheadMenuItem { - title: string; - titleEnglish?: string; - url?: string; - highlighted?: boolean; - megaPanelViewAll?: boolean; - megapanelContent?: MegapanelContent; +export interface L0MenuItem extends BasicLink { + submenu?: L0Megamenu | BasicLink[]; } -/** - * A menu section in masthead. - */ -export interface MastheadMenuSection { - heading?: string; - menuItems: MastheadMenuItem[]; +export interface L0Megamenu { + sections: Megapanel[]; + highlights?: MegapanelLinkGroup[]; + viewAll?: BasicLink; } -/** - * An item in masthead. - */ -export interface MastheadLink { - title: string; - titleEnglish?: string; - url?: string; - hasMenu?: boolean; - hasMegapanel?: boolean; - megamenuLayout?: 'tab' | 'list'; - menuSections?: MastheadMenuSection[]; +export interface Megapanel { + heading?: BasicLink; + groups: MegapanelLinkGroup[]; + viewAll?: BasicLink; } -/** - * A menu section for masthead - * - * @deprecated - */ -export interface LegacyMastheadL1 { - title: string; - url?: string; - menuItems?: MastheadLink[]; +export interface MegapanelLinkGroup { + heading?: BasicLink; + links?: BasicLink[]; } /** @@ -176,12 +136,13 @@ export interface MastheadLogoData { /** * Cloud Masthead Profile content + * + * @deprecated */ export interface MastheadProfileContent { iconLabel: string; links: MastheadProfileItem[]; ctaButtons: MastheadProfileItem[]; - contactUsButton: string; } /** @@ -194,11 +155,16 @@ export interface MiscLabels { * The translation data for ibm.com sites */ export interface Translation { + /** + * Main masthead navigation data. + * + * @deprecated Use masthead.nav instead. + */ mastheadNav: { /** * The nav links. */ - links: MastheadLink[]; + links: L0MenuItem[]; }; /** @@ -211,8 +177,25 @@ export interface Translation { */ footerThin: BasicLink[]; + /** + * Masthead items other than main navigation + */ + masthead: { + logo: MastheadLogoData; + nav: L0MenuItem[]; + contact: MastheadProfileItem; + profileMenu: { + unauthenticated: MastheadProfileItem[]; + authenticated: MastheadProfileItem[]; + signedin: MastheadProfileContent; + signedout: MastheadProfileContent; + }; + }; + /** * The profile menus. + * + * @deprecated Use masthead.profileMenu instead. */ profileMenu: { /** @@ -226,18 +209,6 @@ export interface Translation { signedout: MastheadProfileItem[]; }; - /** - * Cloud masthead items - */ - masthead: { - logo: MastheadLogoData; - contact: MastheadProfileContent; - profileMenu: { - signedout: MastheadProfileContent; - signedin: MastheadProfileContent; - }; - }; - /** * Miscellaneous translations */ @@ -296,29 +267,3 @@ export interface TranslateAPIState { */ errorsRequestTranslation?: { [language: string]: Error }; } - -// New for v2.1.0 -export interface L0Menu { - items: L0MenuItem[]; -} - -export interface L0MenuItem extends BasicLink { - submenu?: L0Megamenu | BasicLink[]; -} - -export interface L0Megamenu { - sections: Megapanel[]; - highlights?: MegapanelLinkGroup[]; - viewAll?: BasicLink; -} - -export interface Megapanel { - heading?: BasicLink; - groups: MegapanelLinkGroup[]; - viewAll?: BasicLink; -} - -export interface MegapanelLinkGroup { - heading?: BasicLink; - links?: BasicLink[]; -} diff --git a/packages/styles/scss/components/masthead/_masthead-l1.scss b/packages/styles/scss/components/masthead/_masthead-l1.scss index 573642ec33b..84881eb680a 100644 --- a/packages/styles/scss/components/masthead/_masthead-l1.scss +++ b/packages/styles/scss/components/masthead/_masthead-l1.scss @@ -13,6 +13,7 @@ @use '@carbon/styles/scss/themes' as *; @use '@carbon/styles/scss/type' as *; @use '@carbon/styles/scss/utilities' as *; +@use '@carbon/styles/scss/utilities/convert' as *; @use '@carbon/styles/scss/components/button/tokens' as *; @use '../../globals/vars' as *; @use 'vars' as *; diff --git a/packages/styles/scss/components/masthead/_masthead-megamenu.scss b/packages/styles/scss/components/masthead/_masthead-megamenu.scss index 5aa22e1ecf8..58d7de698e6 100644 --- a/packages/styles/scss/components/masthead/_masthead-megamenu.scss +++ b/packages/styles/scss/components/masthead/_masthead-megamenu.scss @@ -12,6 +12,7 @@ @use '@carbon/styles/scss/theme' as *; @use '@carbon/styles/scss/type' as *; @use '@carbon/styles/scss/utilities' as *; +@use '@carbon/styles/scss/utilities/convert' as *; @use '../../globals/utils/flex-grid' as *; @use '../../globals/vars' as *; @@ -78,7 +79,6 @@ .#{$prefix}--header__menu-title[aria-expanded='false'] + .#{$prefix}--header__menu { ::slotted(#{$c4d-prefix}-megamenu), - ::slotted(#{$c4d-prefix}-cloud-megamenu), .#{$prefix}--masthead__megamenu { animation: $transition-expansion motion(standard, expressive) collapse; } @@ -99,7 +99,6 @@ visibility: visible; ::slotted(#{$c4d-prefix}-megamenu), - ::slotted(#{$c4d-prefix}-cloud-megamenu), .#{$prefix}--masthead__megamenu { animation: $transition-expansion motion(standard, expressive) expand; } @@ -121,7 +120,6 @@ } :host(#{$c4d-prefix}-megamenu), - :host(#{$c4d-prefix}-cloud-megamenu), .#{$prefix}--masthead__megamenu { @include box-shadow; --#{$c4d-prefix}-masthead-max-height: calc( diff --git a/packages/styles/scss/components/masthead/_masthead.scss b/packages/styles/scss/components/masthead/_masthead.scss index 8ad1a6e9050..5160b2d2192 100755 --- a/packages/styles/scss/components/masthead/_masthead.scss +++ b/packages/styles/scss/components/masthead/_masthead.scss @@ -17,7 +17,9 @@ @use '@carbon/styles/scss/theme' as *; @use '@carbon/styles/scss/themes' as *; @use '@carbon/styles/scss/type' as *; +@use '@carbon/styles/scss/layout' as layout; @use '@carbon/styles/scss/utilities' as *; +@use '@carbon/styles/scss/utilities/convert' as *; @use '../../globals/vars' as *; @use '../link-with-icon'; @use 'vars' as *; @@ -266,8 +268,9 @@ } :host(#{$c4d-prefix}-masthead-composite), - :host(#{$c4d-prefix}-masthead-container), - :host(#{$c4d-prefix}-cloud-masthead-container) { + :host(#{$c4d-prefix}-masthead-container) { + @include layout.emit-layout-tokens(); + position: relative; z-index: 900; display: block; diff --git a/packages/utilities/src/utilities/StickyHeader/StickyHeader.js b/packages/utilities/src/utilities/StickyHeader/StickyHeader.js index 5274b1d40f0..265c03ddfa1 100644 --- a/packages/utilities/src/utilities/StickyHeader/StickyHeader.js +++ b/packages/utilities/src/utilities/StickyHeader/StickyHeader.js @@ -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. diff --git a/packages/web-components/.env.example b/packages/web-components/.env.example index 02cd01fa735..a8bc6fb537f 100644 --- a/packages/web-components/.env.example +++ b/packages/web-components/.env.example @@ -19,4 +19,3 @@ KALTURA_UICONF_ID= # Feature Flags C4D_FLAGS_ALL= -C4D_CLOUD_MASTHEAD= diff --git a/packages/web-components/IMPLEMENTATION_NOTES.md b/packages/web-components/IMPLEMENTATION_NOTES.md index beca75342a1..79574a95aad 100644 --- a/packages/web-components/IMPLEMENTATION_NOTES.md +++ b/packages/web-components/IMPLEMENTATION_NOTES.md @@ -202,6 +202,12 @@ There are some common behaviors in CTA components that are implemented by attribute of `` for `external` CTA types. - [Use a hash link](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/blob/v1.15.0-rc.0/packages/web-components/src/component-mixins/cta/cta.ts#L113-L122) for `video` CTA types. +- Trigger a CTA video on page load using a `#cta-video-[video-id]` URL fragment. + For any page that includes a CTA component composed with `CTAMixin`, the CTA + will look for a URL fragment following the pattern `#cta-video-[video-id]`, + where `[video-id]` is the video id configured for the component. If there is a + match, the CTA will automatically be triggered, which in most cases will open + a lightbox and begin video playback (subject to browser auto-play policies). ### Video CTA diff --git a/packages/web-components/examples/stackblitz/components/cloud-masthead/.gitignore b/packages/web-components/examples/stackblitz/components/cloud-masthead/.gitignore deleted file mode 100644 index d94d6e13e94..00000000000 --- a/packages/web-components/examples/stackblitz/components/cloud-masthead/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -# See https://help.github.com/ignore-files/ for more about ignoring files. - -# dependencies -/node_modules - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.cache -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/packages/web-components/examples/stackblitz/components/cloud-masthead/.sassrc b/packages/web-components/examples/stackblitz/components/cloud-masthead/.sassrc deleted file mode 100644 index c0ad86448e3..00000000000 --- a/packages/web-components/examples/stackblitz/components/cloud-masthead/.sassrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "includePaths": [ - "node_modules", "../../node_modules" - ], -} diff --git a/packages/web-components/examples/stackblitz/components/cloud-masthead/cdn-rtl.html b/packages/web-components/examples/stackblitz/components/cloud-masthead/cdn-rtl.html deleted file mode 100644 index be161cfb984..00000000000 --- a/packages/web-components/examples/stackblitz/components/cloud-masthead/cdn-rtl.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - @carbon/ibmdotcom-web-components example - - - - - - - - - -
-
-
-
-

- Purpose and function -

-

- The shell is perhaps the most crucial piece of any UI built with Carbon. It contains the shared navigation framework - for the entire design system and ties the products in IBM’s portfolio together in a cohesive and elegant way. The - shell is the home of the topmost navigation, where users can quickly and dependably gain their bearings and move - between pages. -
-
- The shell was designed with maximum flexibility built in, to serve the needs of a broad range of products and users. - Adopting the shell ensures compliance with IBM design standards, simplifies development efforts, and provides great - user experiences. All IBM products built with Carbon are required to use the shell’s header. -
-
- To better understand the purpose and function of the UI shell, consider the “shell” of MacOS, which contains the - Apple menu, top-level navigation, and universal, OS-level controls at the top of the screen, as well as a universal - dock along the bottom or side of the screen. The Carbon UI shell is roughly analogous in function to these parts of - the Mac UI. For example, the app switcher portion of the shell can be compared to the dock in MacOS. -

-

- Header responsive behavior -

-

- As a header scales down to fit smaller screen sizes, headers with persistent side nav menus should have the side nav - collapse into “hamburger” menu. See the example to better understand responsive behavior of the header. -

-

- Secondary navigation -

-

- The side-nav contains secondary navigation and fits below the header. It can be configured to be either fixed-width - or flexible, with only one level of nested items allowed. Both links and category lists can be used in the side-nav - and may be mixed together. There are several configurations of the side-nav, but only one configuration should be - used per product section. If tabs are needed on a page when using a side-nav, then the tabs are secondary in - hierarchy to the side-nav. -

-
-
-
-
- - diff --git a/packages/web-components/examples/stackblitz/components/cloud-masthead/cdn.html b/packages/web-components/examples/stackblitz/components/cloud-masthead/cdn.html deleted file mode 100644 index b0d8957e2d5..00000000000 --- a/packages/web-components/examples/stackblitz/components/cloud-masthead/cdn.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - @carbon/ibmdotcom-web-components example - - - - - - - - - -
-
-
-
-

- Purpose and function -

-

- The shell is perhaps the most crucial piece of any UI built with Carbon. It contains the shared navigation framework - for the entire design system and ties the products in IBM’s portfolio together in a cohesive and elegant way. The - shell is the home of the topmost navigation, where users can quickly and dependably gain their bearings and move - between pages. -
-
- The shell was designed with maximum flexibility built in, to serve the needs of a broad range of products and users. - Adopting the shell ensures compliance with IBM design standards, simplifies development efforts, and provides great - user experiences. All IBM products built with Carbon are required to use the shell’s header. -
-
- To better understand the purpose and function of the UI shell, consider the “shell” of MacOS, which contains the - Apple menu, top-level navigation, and universal, OS-level controls at the top of the screen, as well as a universal - dock along the bottom or side of the screen. The Carbon UI shell is roughly analogous in function to these parts of - the Mac UI. For example, the app switcher portion of the shell can be compared to the dock in MacOS. -

-

- Header responsive behavior -

-

- As a header scales down to fit smaller screen sizes, headers with persistent side nav menus should have the side nav - collapse into “hamburger” menu. See the example to better understand responsive behavior of the header. -

-

- Secondary navigation -

-

- The side-nav contains secondary navigation and fits below the header. It can be configured to be either fixed-width - or flexible, with only one level of nested items allowed. Both links and category lists can be used in the side-nav - and may be mixed together. There are several configurations of the side-nav, but only one configuration should be - used per product section. If tabs are needed on a page when using a side-nav, then the tabs are secondary in - hierarchy to the side-nav. -

-
-
-
-
- - diff --git a/packages/web-components/examples/stackblitz/components/cloud-masthead/index.html b/packages/web-components/examples/stackblitz/components/cloud-masthead/index.html deleted file mode 100644 index 981e6c2caf7..00000000000 --- a/packages/web-components/examples/stackblitz/components/cloud-masthead/index.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - @carbon/ibmdotcom-web-components example - - - - - - - -
-
-
-
-

- Purpose and function -

-

- The shell is perhaps the most crucial piece of any UI built with Carbon. It contains the shared navigation framework - for the entire design system and ties the products in IBM’s portfolio together in a cohesive and elegant way. The - shell is the home of the topmost navigation, where users can quickly and dependably gain their bearings and move - between pages. -
-
- The shell was designed with maximum flexibility built in, to serve the needs of a broad range of products and users. - Adopting the shell ensures compliance with IBM design standards, simplifies development efforts, and provides great - user experiences. All IBM products built with Carbon are required to use the shell’s header. -
-
- To better understand the purpose and function of the UI shell, consider the “shell” of MacOS, which contains the - Apple menu, top-level navigation, and universal, OS-level controls at the top of the screen, as well as a universal - dock along the bottom or side of the screen. The Carbon UI shell is roughly analogous in function to these parts of - the Mac UI. For example, the app switcher portion of the shell can be compared to the dock in MacOS. -

-

- Header responsive behavior -

-

- As a header scales down to fit smaller screen sizes, headers with persistent side nav menus should have the side nav - collapse into “hamburger” menu. See the example to better understand responsive behavior of the header. -

-

- Secondary navigation -

-

- The side-nav contains secondary navigation and fits below the header. It can be configured to be either fixed-width - or flexible, with only one level of nested items allowed. Both links and category lists can be used in the side-nav - and may be mixed together. There are several configurations of the side-nav, but only one configuration should be - used per product section. If tabs are needed on a page when using a side-nav, then the tabs are secondary in - hierarchy to the side-nav. -

-
-
-
-
- - diff --git a/packages/web-components/examples/stackblitz/components/cloud-masthead/package.json b/packages/web-components/examples/stackblitz/components/cloud-masthead/package.json deleted file mode 100644 index 30995b83ae1..00000000000 --- a/packages/web-components/examples/stackblitz/components/cloud-masthead/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "ibmdotcom-web-components-cloud-masthead-example", - "version": "0.1.0", - "private": true, - "description": "Sample project for getting started with the Web Components from Carbon for IBM.com.", - "license": "Apache-2", - "main": "index.html", - "scripts": { - "clean": "rimraf node_modules dist .cache", - "start": "parcel index.html --port=9000 --no-hmr", - "build": "parcel build *.html --no-minify --public-url ./" - }, - "dependencies": { - "@carbon/ibmdotcom-web-components": "latest" - }, - "devDependencies": { - "@babel/core": "^7.0.0-0", - "carbon-components": "^10.36.0", - "parcel-bundler": "1.12.3", - "rimraf": "^3.0.2", - "sass": "^1.32.13" - } -} diff --git a/packages/web-components/examples/stackblitz/components/cloud-masthead/src/index-cdn.js b/packages/web-components/examples/stackblitz/components/cloud-masthead/src/index-cdn.js deleted file mode 100644 index 55686b8a66d..00000000000 --- a/packages/web-components/examples/stackblitz/components/cloud-masthead/src/index-cdn.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2020, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -window.digitalData = { - page: { - pageInfo: { - language: 'en-US', - ibm: { - country: 'US', - siteID: 'IBMTESTWWW', - }, - }, - isDataLayerReady: true, - }, -}; diff --git a/packages/web-components/examples/stackblitz/components/cloud-masthead/src/index.js b/packages/web-components/examples/stackblitz/components/cloud-masthead/src/index.js deleted file mode 100644 index 6160f4834c6..00000000000 --- a/packages/web-components/examples/stackblitz/components/cloud-masthead/src/index.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2020, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import '@carbon/ibmdotcom-web-components/es/components/masthead/cloud/index.js'; -import './index.scss'; - -window.digitalData = { - page: { - pageInfo: { - language: 'en-US', - ibm: { - country: 'US', - siteID: 'IBMTESTWWW', - }, - }, - isDataLayerReady: true, - }, -}; diff --git a/packages/web-components/examples/stackblitz/components/cloud-masthead/src/index.scss b/packages/web-components/examples/stackblitz/components/cloud-masthead/src/index.scss deleted file mode 100644 index 3fcda169c02..00000000000 --- a/packages/web-components/examples/stackblitz/components/cloud-masthead/src/index.scss +++ /dev/null @@ -1,37 +0,0 @@ -// -// @license -// -// Copyright IBM Corp. 2020, 2023 -// -// This source code is licensed under the Apache-2.0 license found in the -// LICENSE file in the root directory of this source tree. -// - -// `enable-css-custom-properties` and `grid-columns-16` feature flags are requirements for Carbon for IBM.com styles -$feature-flags: ( - enable-css-custom-properties: true, - grid-columns-16: true, -); - -@import 'carbon-components/scss/globals/grid/grid'; -@import 'carbon-components/scss/components/ui-shell/content'; - -body { - padding: calc(#{$spacing-09} + #{mini-units(6)} + 1px) $spacing-09 $spacing-09 $spacing-09; -} - -@media (min-width: 66rem) { - .cds--offset-lg-3 { - margin-left: 0; - } -} - -.cds--content.cds-ce-demo--ui-shell-content { - h2 { - margin: 30px 0; - - &:first-of-type { - margin-top: 0; - } - } -} diff --git a/packages/web-components/src/component-mixins/cta/cta.ts b/packages/web-components/src/component-mixins/cta/cta.ts index 8aaa313a822..31d7c5cad95 100644 --- a/packages/web-components/src/component-mixins/cta/cta.ts +++ b/packages/web-components/src/component-mixins/cta/cta.ts @@ -1,7 +1,7 @@ /** * @license * - * Copyright IBM Corp. 2020, 2023 + * Copyright IBM Corp. 2020, 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. @@ -29,6 +29,7 @@ import { formatVideoCaption, formatVideoDuration, } from '../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/formatVideoCaption/formatVideoCaption.js'; +import root from 'window-or-global'; const { prefix, stablePrefix: c4dPrefix } = settings; @@ -201,6 +202,14 @@ const CTAMixin = >(Base: T) => { `; } + firstUpdated() { + const { ctaType, href } = this; + // Check for the URL trigger meant to fire eventRunAction. + if (ctaType === CTA_TYPE.VIDEO && href) { + this._checkUrlVideoTrigger(); + } + } + /** * Handles `.updated()` method of `lit-element`. */ @@ -324,6 +333,46 @@ const CTAMixin = >(Base: T) => { } } + /** + * Check the URL for a fragment including the video id. + * + * If we find a URL fragment that includes the video id, we trigger the + * eventRunAction event, which for video will open the video and start + * playback in a lightbox. This is the same thing that happens when the user + * clicks on the CTA. + */ + _checkUrlVideoTrigger() { + const { ctaType, disabled, href, videoDescription, videoName } = this; + // Without a video id, or if the button is disabled, there is nothing to + // do here. + if (ctaType !== CTA_TYPE.VIDEO || !href || disabled) { + return; + } + // Only trigger for the first CTA with the video id in the page. + if (this.ownerDocument.querySelector(`[href='${href}']`) !== this) { + return; + } + const { eventRunAction } = this.constructor as typeof CTAMixinImpl; + const hash = root.location.hash; + const urlTrigger = `cta-video-${href}`; + + if (hash === `#${urlTrigger}`) { + this.dispatchEvent( + new CustomEvent(eventRunAction, { + bubbles: true, + cancelable: true, + composed: true, + detail: { + href, + ctaType, + videoName, + videoDescription, + }, + }) + ); + } + } + /** * Updates video thumbnail url to match card width. */ diff --git a/packages/web-components/src/components/dotcom-shell/__stories__/dotcom-shell.stories.ts b/packages/web-components/src/components/dotcom-shell/__stories__/dotcom-shell.stories.ts index 6513798093d..6c792def0a0 100644 --- a/packages/web-components/src/components/dotcom-shell/__stories__/dotcom-shell.stories.ts +++ b/packages/web-components/src/components/dotcom-shell/__stories__/dotcom-shell.stories.ts @@ -1,7 +1,7 @@ /** * @license * - * Copyright IBM Corp. 2020, 2023 + * Copyright IBM Corp. 2020, 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. @@ -22,7 +22,7 @@ import { import mastheadStyles from '../../masthead/__stories__/masthead.stories.scss'; import { FOOTER_SIZE } from '../../footer/footer'; import { - mastheadLinksV2 as l0Data, + mastheadL0Data as l0Data, mastheadL1Data as l1Data, } from '../../masthead/__stories__/links'; import mockLangList from '../../footer/__stories__/language-list'; diff --git a/packages/web-components/src/components/expressive-modal/expressive-modal.ts b/packages/web-components/src/components/expressive-modal/expressive-modal.ts index dfd56b21708..801c4198b9a 100644 --- a/packages/web-components/src/components/expressive-modal/expressive-modal.ts +++ b/packages/web-components/src/components/expressive-modal/expressive-modal.ts @@ -1,7 +1,7 @@ /** * @license * - * Copyright IBM Corp. 2020, 2023 + * Copyright IBM Corp. 2020, 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. @@ -530,7 +530,7 @@ class C4DExpressiveModal extends StableSelectorMixin( static get selectorPrimaryFocus() { return ` [data-modal-primary-focus], - ${c4dPrefix}-expressive-modal-footer ${c4dPrefix}-button[kind="primary"], + ${c4dPrefix}-expressive-modal-footer ${c4dPrefix}-button[kind="primary"] `; } diff --git a/packages/web-components/src/components/masthead/__stories__/README.stories.mdx b/packages/web-components/src/components/masthead/__stories__/README.stories.mdx index ffad4eaecc6..641b6ad682d 100644 --- a/packages/web-components/src/components/masthead/__stories__/README.stories.mdx +++ b/packages/web-components/src/components/masthead/__stories__/README.stories.mdx @@ -1,8 +1,6 @@ import { - Preview, Props, Description, - Story, } from '@storybook/addon-docs/blocks'; import contributing from '../../../../../../docs/contributing-license.md'; import { cdnJs, cdnCss } from '../../../globals/internal/storybook-cdn'; @@ -13,6 +11,8 @@ import { cdnJs, cdnCss } from '../../../globals/internal/storybook-cdn'; > displays consistently at the top of each page. It also includes search and > profile services for IBM.com. +## Examples + > 💡 Check our > [Stackblitz](https://stackblitz.com/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/web-components/examples/stackblitz/components/masthead) > example implementation. @@ -25,92 +25,48 @@ import { cdnJs, cdnCss } from '../../../globals/internal/storybook-cdn'; [![Edit @carbon/ibmdotcom-web-components](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/web-components/examples/stackblitz/components/masthead-l1) -## Getting Started +## Getting started -##### Note: Masthead uses the Carbon White theme by design. Using other themes will not change the Masthead color scheme. +**Note: Masthead uses the Carbon White theme by design. Using other themes will not change the Masthead color scheme.** ### JS (via import) -````javascript -import '@carbon/ibmdotcom-web-components/es/components/masthead/masthead-container.js'; -``` - - -### HTML - -```html - -```` - -#### Adopting Masthead v2 with new data endpoint - -###### JS (via CDN): - -```html -// Alpha tag using changes from the feature branch (feat/masthead-v2) - -``` - -###### Markup: - -```html - -``` - -#### Adopting Masthead v2 with Cloud data endpoint - -###### JS (via CDN): - -```html -// Alpha tag using changes from the feature branch (feat/masthead-v2) - +```javascript +import '@carbon/ibmdotcom-web-components/es/components/masthead'; ``` -###### Markup: + + +### HTML +Using the default data provides visitors a consistent navigation experience across web properties. ```html + data-endpoint="/common/carbon-for-ibm-dotcom/translations/masthead-footer/v2.1" +> ``` -#### Setting Platform +## Modifying the masthead +### Setting platform name ```html ``` -#### Setting Platform URL - -The `platformUrl` property accepts a single URL as string or an object with a -specific URL for each locale. This property has to be set via javascript. - -###### Setting a single platform URL: - +### Setting platform URL ```html + id="masthead"> ``` ```javascript -const singleUrl = 'https://www.example.com'; - -document.getElementById('masthead-container').platformUrl = singleUrl; +document.getElementById('masthead').platformUrl = 'https://www.example.com'; ``` -###### Setting multiple platform URLs with an object: +#### Localized platform URLs -With an object, the component will show a specific URL depending on the locale: +The component will show a specific URL depending on the locale if you set the `platformUrl` property to an object, like so: ```javascript const urlObject = { @@ -125,32 +81,74 @@ const urlObject = { }, }; -document.getElementById('masthead-container').platformUrl = urlObject; +document.getElementById('masthead').platformUrl = urlObject; ``` +### Custom navigation + +In order to set custom navigation for the masthead, use JavaScript to set the `navLinks` property of the masthead-composite component. This property should be an array of `L0MenuItem` objects as defined in [the services-store package](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/blob/main/packages/services-store/src/types/translateAPI.ts). + ```html - + +``` + +```javascript +const customNavData = [ + { + title: 'Basic Link', + titleEnglish: 'Basic Link', + url: 'https://www.example.com/', + }, + { + title: 'Dropdown', + titleEnglish: 'Dropdown', + submenu: [ + { + title: 'Dropdown Link', + titleEnglish: 'Dropdown Link', + url: 'https://www.example.com/demo', + }, + { + title: 'Dropdown Link 2', + titleEnglish: 'Dropdown Link 2', + url: 'https://www.example.com/demo-2', + }, + ], + }, + { + title: 'Megamenu', + titleEnglish: 'Megamenu', + submenu: { + sections: [...], + viewAll: {...}, + }, + }, +]; +document.getElementById('masthead').navLinks = customNavData; ``` -#### Custom Navigation +#### Custom data endpoint -In order to set custom navigation for the masthead, set the custom navigation -data to the `customNavLinks` property of the masthead-container component. +To set a custom endpoint for the translation service to fetch from, set either +the `data-endpoint` attribute like below or `C4D_TRANSLATION_ENDPOINT` +environment variable. -```javascript -const links = [...menu items...]; -document.getElementById('masthead-container').customNavLinks = links; +```html + ``` -#### Using L1 nav +### Using L1 Nav -To use L1 nav, set `l1Data` prop. `l1Data` prop should be a MastheadL1 object, -as defined in packages/services-store/src/actions/translateAPI.ts that contains -the navigation data of L1 nav: +To use L1 nav, set `l1Data` property in JavaScript. It should be a `MastheadL1` object, as defined in [the services-store package](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/blob/main/packages/services-store/src/types/translateAPI.ts). -```javascipt +```html + +``` + +```javascript const l1Data = { platform: { name: 'Stock Charts', @@ -159,19 +157,8 @@ const l1Data = { menuItems: [...], actions: {...}, } -``` -```html - -``` - -To set a custom endpoint for the translation service to fetch from, set either -the `data-endpoint` attribute like below or `C4D_TRANSLATION_ENDPOINT` -environment variable. - -```html - +document.getElementById('masthead').l1Data = l1Data; ``` ### Setting the active menu item @@ -179,19 +166,23 @@ environment variable. The active menu item receives a unique style treatment to indicate where the current page is within the navigation hierarchy. -##### Manually - -Manually set the active item by using the `selected-menu-item` property. See -[the Props table](#props). +> Note: If no menu items are marked active and the optional `platformUrl` property +has been set, the platform link will be marked active. -##### Automatically +#### Automatically The first menu item whose `href` value matches the browser window's current URL will automatically be marked active if the `selected-menu-item` property has not been set. -If no other menu items are marked active and the optional `platformUrl` property -has been set, the platform link will be marked active. +#### Manually + +Manually set the active item by using the `selected-menu-item` property. Any navigation items with a matching `titleEnglish` value from the `navLinks` data will be marked active. + +```html + +``` ### Understanding the different authentication method types @@ -211,7 +202,9 @@ method. See below for more context on each available value. console API user login response. This method is designed and intended for Cloud Docs (https://cloud.ibm.com) team usage only. -## Using custom search with typeahead API +### Customizing search + +#### Using custom search with typeahead API Using a search API other than the default provided from IBM Search is supported. @@ -226,14 +219,11 @@ As an example, we will be using the IBM Docs API to fetch the data, retrieving an array of result suggestions. ```javascript -async function customTypeaheadApiFunction(searchVal) { - return fetch( - `https://ibmdocs-dev.mybluemix.net/docs/api/v1/suggest?query=${searchVal}&lang=en&categories=&limit=6` - ) - .then((response) => response.json()) - .then((data) => { - let searchResults = [data.hints]; - return searchResults; +async function customTypeaheadApiFunction(query) { + return fetch(`https://www-api.ibm.com/search/typeahead/v1?query=${query}`) + .then(response => response.json()) + .then(data => { + return [data.response.map(result => result[0])]; }); } ``` @@ -241,8 +231,8 @@ async function customTypeaheadApiFunction(searchVal) { To query the current masthead search input, we need to create an event listener to listen for the `c4d-search-with-typeahead-input` event. Once captured, we need to call our asynchronous function to fetch the custom API results based on -the query. Once the results are retrieved, a new custom event -`c4d-custom-typeahead-api-results` needs to be dispatched containing the results +the query. Once the results are retrieved, a new custom event - +`c4d-custom-typeahead-api-results` - needs to be dispatched containing the results for the component to render the search suggestions. ```javascript @@ -254,30 +244,35 @@ document.addEventListener('c4d-search-with-typeahead-input', async (e) => { }); ``` -### Grouped Search +#### Grouped search Some APIs contain grouped results in addition to regular search suggestions, which can also be displayed upon search. As before, create a function that fetches the query and make sure to include a JSON object containing the section's `title` and the array of retrieved section -suggestions in `items`. In the example below, the section `Product pages` is +suggestions in `items`. In the example below, the `Carbon` section is added to the results array. ```javascript -async function customTypeaheadApiFunction(searchVal) { - return fetch( - `https://ibmdocs-dev.mybluemix.net/docs/api/v1/suggest?query=${searchVal}&lang=en&categories=&limit=6` - ) +async function customTypeaheadApiFunction(query) { + return fetch(`https://www-api.ibm.com/search/typeahead/v1?query=${query}`) .then((response) => response.json()) .then((data) => { let searchResults = [ - data.hints, - - // optional category results fetched from API + // Results not including "carbon" + data.response + .filter(result => !result[0].toLowerCase().includes('carbon')) + .map(result => result[0]), + // Optional grouped category results including "carbon" { - title: 'Product pages', - items: data.products, + title: 'Carbon', + items: data.response + .filter(result => result[0].toLowerCase().includes('carbon')) + .map(result => ({ + name: result[0], + href: `https://www.example.com/${encodeURIComponent(result[0])}` + })), }, ]; return searchResults; @@ -289,7 +284,7 @@ As mentioned above, the two events `c4d-search-with-typeahead-input` and `c4d-custom-typeahead-api-results` must be handled for suggestions to be rendered -- the same code for the event listener can be reused. -#### Note +##### Note The API results must match the following structure: @@ -298,19 +293,45 @@ The API results must match the following structure: ['result 1', 'result 2', 'result 3'], { title: 'Example group 1' - items: ['result a', 'result b', 'result c'] + items: [ + { + name: 'result a', + url: 'https://www.example.com/a', + }, + { + name: 'result b', + url: 'https://www.example.com/b', + }, + { + name: 'result c', + url: 'https://www.example.com/c', + }, + ] }, { title: "Example group 2", - items: ['result d', 'result e', 'result f'] + items: [ + { + name: 'result d', + url: 'https://www.example.com/d', + }, + { + name: 'result e', + url: 'https://www.example.com/e', + }, + { + name: 'result f', + url: 'https://www.example.com/f', + }, + ], } ] ``` -Note that only the first array element is necessary to render the basic search -suggestions, the following JSON objects are optional Grouped sections. +The first array element is required to render the basic search +suggestions, and the following JSON objects are optional grouped sections. -## Scoped search +#### Scoped search Scoped searches are also supported, returning results from specifically targeted IBM pages and products. @@ -350,7 +371,7 @@ const scopeParameters = [ ]; ``` -#### Note +##### Note A list of the available scoped categories can be found [here](https://github.ibm.com/digital-marketplace/columbus/blob/master/docs/SCOPED.MD). @@ -389,16 +410,6 @@ document.querySelector('c4d-search-with-typeahead').placeholderFormatter = -For Cloud-specific version of masthead-container, -``, we support two user authentication methods, -via cookie or api. To select between the two, provide the `auth-method` prop -with a value of either 'cookie' or 'api'. - -```html - -``` - ## Stable selectors See diff --git a/packages/web-components/src/components/masthead/__stories__/README.stories.react.mdx b/packages/web-components/src/components/masthead/__stories__/README.stories.react.mdx index 5caf6c3c655..6e7c480f8df 100644 --- a/packages/web-components/src/components/masthead/__stories__/README.stories.react.mdx +++ b/packages/web-components/src/components/masthead/__stories__/README.stories.react.mdx @@ -1,8 +1,6 @@ import { - Preview, Props, Description, - Story, } from '@storybook/addon-docs/blocks'; import contributing from '../../../../../../docs/contributing-license.md'; import { PropTypesRef } from '@carbon/ibmdotcom-web-components/es/components-react/masthead/masthead-composite.js'; @@ -13,6 +11,8 @@ import { PropTypesRef } from '@carbon/ibmdotcom-web-components/es/components-rea > displays consistently at the top of each page. It also includes search and > profile services for IBM.com. +## Examples + > 💡 Check our > [Stackblitz](https://stackblitz.com/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/web-components/examples/stackblitz/components-react/masthead) > example implementation. @@ -27,54 +27,45 @@ import { PropTypesRef } from '@carbon/ibmdotcom-web-components/es/components-rea ## Getting Started -##### Note: Masthead uses the Carbon White theme by design. Using other themes will not change the Masthead color scheme. +**Note: Masthead uses the Carbon White theme by design. Using other themes will not change the Masthead color scheme.** -### JS +Using the default data provides visitors a consistent navigation experience across web properties. ```javascript import C4DMastheadContainer from '@carbon/ibmdotcom-web-components/es/components-react/masthead/masthead-container.js'; function App() { - return ; -} -``` - -#### Setting Platform - -```javascript -function App() { - return ; + return ( + + ); } ``` -#### Setting Platform URL +## Modifying the masthead -The `platformUrl` property accepts a single URL as string or an object with a -specific URL for each locale. This property has to be set via javascript. - -###### Setting a single platform URL: +### Setting platform name and URL ```javascript function App() { return ( - ); + platformUrl="https://www.example.com"> + ); } ``` -```javascript -const singleUrl = 'https://www.example.com'; - -document.getElementById('masthead-container').platformUrl = singleUrl; -``` - -###### Setting multiple platform URLs with an object: +#### Localized platform URLs -With an object, the component will show a specific URL depending on the locale: +The `platformUrl` property can also be set to an object to show a specific URL depending on the locale. ```javascript +function App() { + return ; +} + const urlObject = { 'en-US': { url: 'https://www.example.com', @@ -87,60 +78,88 @@ const urlObject = { }, }; -document.getElementById('masthead-container').platformUrl = urlObject; +document.querySelector('c4d-masthead-container').platformUrl = urlObject; ``` +### Custom navigation + +In order to set custom navigation for the masthead, set the `navLinks` property of the masthead-composite component. This property should be an array of `L0MenuItem` objects as defined in [the services-store package](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/blob/main/packages/services-store/src/types/translateAPI.ts). + ```javascript function App() { - return ( - - ); + return ; } -``` - -#### Custom Navigation -In order to set custom navigation for the masthead, set the custom navigation -data to the `customNavLinks` property of the masthead-container component. +const customNavData = [ + { + title: 'Basic Link', + titleEnglish: 'Basic Link', + url: 'https://www.example.com/', + }, + { + title: 'Dropdown', + titleEnglish: 'Dropdown', + submenu: [ + { + title: 'Dropdown Link', + titleEnglish: 'Dropdown Link', + url: 'https://www.example.com/demo', + }, + { + title: 'Dropdown Link 2', + titleEnglish: 'Dropdown Link 2', + url: 'https://www.example.com/demo-2', + }, + ], + }, + { + title: 'Megamenu', + titleEnglish: 'Megamenu', + submenu: { + sections: [...], + viewAll: {...}, + }, + }, +]; -```javascript -const links = [...menu items...]; -document.getElementById('masthead-container').customNavLinks = links; +document.querySelector('c4d-masthead-container').navLinks = customNavData; ``` -#### Using L1 nav +#### Custom data endpoint -To use L1 nav, set `l1Data` prop. `l1Data` prop should be an object that -contains the navigation data of L1 nav: - -```javascipt -const l1Data = { - platform: { - name: 'Stock Charts', - url: 'https://example.com/', - }, - menuItems: (The nav links), -} -``` +To set a custom endpoint for the translation service to fetch from, set either +the `data-endpoint` attribute like below or `C4D_TRANSLATION_ENDPOINT` +environment variable. ```javascript function App() { - return ; + return ( + + ); } ``` -To set a custom endpoint for the translation service to fetch from, set either -the `data-endpoint` attribute like below or `C4D_TRANSLATION_ENDPOINT` -environment variable. +### Using L1 nav + +To use L1 nav, set `l1Data` property. It should be a `MastheadL1` object, as defined in [the services-store package](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/blob/main/packages/services-store/src/types/translateAPI.ts). ```javascript function App() { return ( - + ); } + +const l1Data = { + platform: { + name: 'Stock Charts', + url: 'https://example.com/', + }, + menuItems: [...], + actions: {...}, +} + +document.querySelector('c4d-masthead-container').l1Data = l1Data; ``` ### Setting the active menu item @@ -148,21 +167,31 @@ function App() { The active menu item receives a unique style treatment to indicate where the current page is within the navigation hierarchy. -##### Manually - -Manually set the active item by using the `selected-menu-item` property. See -[the Props table](#props). +> Note: If no menu items are marked active and the optional `platformUrl` property +has been set, the platform link will be marked active. -##### Automatically +#### Automatically The first menu item whose `href` value matches the browser window's current URL will automatically be marked active if the `selected-menu-item` property has not been set. -If no other menu items are marked active and the optional `platformUrl` property -has been set, the platform link will be marked active. +#### Manually -## Using custom search with typeahead API +Manually set the active item by using the `selected-menu-item` property. Any navigation items with a matching `titleEnglish` value from the `navLinks` data will be marked active. + +```javascript +function App() { + return ( + + ); +} +``` + +### Customizing search + +#### Using custom search with typeahead API Using a search API other than the default provided from IBM Search is supported. @@ -175,36 +204,38 @@ function App() { ); } +``` -async function customTypeaheadApiFunction(searchVal) { - return fetch( - `https://ibmdocs-dev.mybluemix.net/docs/api/v1/suggest?query=${searchVal}&lang=en&categories=&limit=6` - ) - .then((response) => response.json()) - .then((data) => { - let searchResults = [data.hints]; - return searchResults; +As an example, we will be using the IBM Docs API to fetch the data, retrieving +an array of result suggestions. + +```javascript +async function customTypeaheadApiFunction(query) { + return fetch(`https://www-api.ibm.com/search/typeahead/v1?query=${query}`) + .then(response => response.json()) + .then(data => { + return [data.response.map(result => result[0])]; }); } ``` To query the current masthead search input, we need to create an event listener -to listen for the `cds-search-with-typeahead-input` event. Once captured, we +to listen for the `c4d-search-with-typeahead-input` event. Once captured, we need to call our asynchronous function to fetch the custom API results based on -the query. Once the results are retrieved, a new custom event -`cds-custom-typeahead-api-results` needs to be dispatched containing the results +the query. Once the results are retrieved, a new custom event - +`c4d-custom-typeahead-api-results` - needs to be dispatched containing the results for the component to render the search suggestions. ```javascript -document.addEventListener('cds-search-with-typeahead-input', async (e) => { +document.addEventListener('c4d-search-with-typeahead-input', async (e) => { const results = await customTypeaheadApiFunction(e.detail.value); document.dispatchEvent( - new CustomEvent('cds-custom-typeahead-api-results', { detail: results }) + new CustomEvent('c4d-custom-typeahead-api-results', { detail: results }) ); }); ``` -### Grouped Search +#### Grouped Search Some APIs contain grouped results in addition to regular search suggestions, which can also be displayed upon search. @@ -215,19 +246,24 @@ suggestions in `items`. In the example below, the section `Product pages` is added to the results array. ```javascript -async function customTypeaheadApiFunction(searchVal) { - return fetch( - `https://ibmdocs-dev.mybluemix.net/docs/api/v1/suggest?query=${searchVal}&lang=en&categories=&limit=6` - ) +async function customTypeaheadApiFunction(query) { + return fetch(`https://www-api.ibm.com/search/typeahead/v1?query=${query}`) .then((response) => response.json()) .then((data) => { let searchResults = [ - data.hints, - - // optional category results fetched from API + // Results not including "carbon" + data.response + .filter(result => !result[0].toLowerCase().includes('carbon')) + .map(result => result[0]), + // Optional grouped category results including "carbon" { - title: 'Product pages', - items: data.products, + title: 'Carbon', + items: data.response + .filter(result => result[0].toLowerCase().includes('carbon')) + .map(result => ({ + name: result[0], + href: `https://www.example.com/${encodeURIComponent(result[0])}` + })), }, ]; return searchResults; @@ -235,11 +271,11 @@ async function customTypeaheadApiFunction(searchVal) { } ``` -As mentioned above, the two events `cds-search-with-typeahead-input` and -`cds-custom-typeahead-api-results` must be handled for suggestions to be +As mentioned above, the two events `c4d-search-with-typeahead-input` and +`c4d-custom-typeahead-api-results` must be handled for suggestions to be rendered -- the same code for the event listener can be reused. -#### Note +##### Note The API results must match the following structure: @@ -248,11 +284,37 @@ The API results must match the following structure: ['result 1', 'result 2', 'result 3'], { title: 'Example group 1' - items: ['result a', 'result b', 'result c'] + items: [ + { + name: 'result a', + url: 'https://www.example.com/a', + }, + { + name: 'result b', + url: 'https://www.example.com/b', + }, + { + name: 'result c', + url: 'https://www.example.com/c', + }, + ] }, { title: "Example group 2", - items: ['result d', 'result e', 'result f'] + items: [ + { + name: 'result d', + url: 'https://www.example.com/d', + }, + { + name: 'result e', + url: 'https://www.example.com/e', + }, + { + name: 'result f', + url: 'https://www.example.com/f', + }, + ], } ] ``` @@ -260,7 +322,7 @@ The API results must match the following structure: Note that only the first array element is necessary to render the basic search suggestions, the following JSON objects are optional Grouped sections. -## Scoped search +#### Scoped search Scoped searches are also supported, returning results from specifically targeted IBM pages and products. @@ -300,16 +362,14 @@ const scopeParameters = [ ]; ``` -#### Note +##### Note A list of the available scoped categories can be found [here](https://github.ibm.com/digital-marketplace/columbus/blob/master/docs/SCOPED.MD). The `value` property can either be a single string, or an array of strings. -This array will be passed into the `scopeParameters` property. If using -`lit-html` to render your page, this can be added using `.scopeParameters` (note -the `.`), in order for the array to be processed properly in the component. +This array will be passed into the `scopeParameters` property. ```javascript function App() { @@ -323,7 +383,7 @@ function App() { Alternatively, JavaScript can be used to insert it into the component. ```javascript -document.querySelector('cds-masthead-composite').scopeParameters = +document.querySelector('c4d-masthead-composite').scopeParameters = scopeParameters; ``` @@ -333,7 +393,7 @@ scope. ```javascript const placeholderFormatter = ({ scopeValue }) => `Buscar en ${scopeValue}`; -document.querySelector('cds-search-with-typeahead').placeholderFormatter = +document.querySelector('c4d-search-with-typeahead').placeholderFormatter = placeholderFormatter; ``` @@ -341,7 +401,7 @@ document.querySelector('cds-search-with-typeahead').placeholderFormatter = -[cds-masthead-container props](https://carbon-design-system.github.io/carbon-for-ibm-dotcom/canary/web-components/?path=/docs/components-masthead--with-alternate-logo-and-tooltip#props) +[c4d-masthead-container props](https://carbon-design-system.github.io/carbon-for-ibm-dotcom/canary/web-components/?path=/docs/components-masthead--with-alternate-logo-and-tooltip#props) For Cloud-specific version of masthead-container, ``, we support two user authentication methods, diff --git a/packages/web-components/src/components/masthead/__stories__/cloud-masthead.stories.ts b/packages/web-components/src/components/masthead/__stories__/cloud-masthead.stories.ts deleted file mode 100644 index af4742631a8..00000000000 --- a/packages/web-components/src/components/masthead/__stories__/cloud-masthead.stories.ts +++ /dev/null @@ -1,176 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2021, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import { html } from 'lit'; -import { select } from '@storybook/addon-knobs'; -import on from '../../../internal/vendor/@carbon/web-components/globals/mixins/on.js'; -import { ifDefined } from 'lit/directives/if-defined.js'; -import inPercy from '@percy-io/in-percy'; -import c4dLeftNav from '../left-nav'; -import '../masthead-container'; -import '../cloud/cloud-masthead-container'; -import styles from './masthead.stories.scss'; -import { mastheadLinks as links } from './links'; -import { - authenticatedProfileItems, - unauthenticatedProfileItems, -} from './profile-items'; -import readme from './README.stories.mdx'; -import textNullable from '../../../../.storybook/knob-text-nullable'; - -/** - * platform knob data - */ -const platformData = { - name: 'IBM Cloud', - url: 'https://www.ibm.com/cloud', -}; - -const urlObject = { - default: { - url: 'https://www.ibm.com/cloud', - }, - 'en-US': { - url: 'https://www.ibm.com/us-en/cloud', - }, - 'fr-FR': { - url: 'https://www.ibm.com/fr-fr/cloud', - }, - 'es-MX': { - url: 'https://www.ibm.com/es-mx/cloud', - }, -}; - -export const Default = (args) => { - const { - hasContact, - hasProfile, - hasSearch, - selectedMenuItem, - searchPlaceholder, - userStatus, - navLinks, - redirectPath, - authMethod, - } = args?.CloudMastheadComposite ?? {}; - const { useMock } = args?.Other ?? {}; - return html` - - ${useMock - ? html` - - ` - : html` - - `} - `; -}; - -export default { - title: 'Experimental/Cloud masthead', - decorators: [ - (story) => { - if (!(window as any)._hPageShow) { - (window as any)._hPageShow = on(window, 'pageshow', () => { - const leftNav = document.querySelector('c4d-left-nav'); - if (leftNav) { - (leftNav as c4dLeftNav).expanded = false; - } - }); - } - return story(); - }, - ], - parameters: { - ...readme.parameters, - 'carbon-theme': { disabled: true }, - percy: { - skip: true, - }, - knobs: { - escapeHTML: false, - CloudMastheadComposite: () => ({ - userStatus: select( - 'The user authenticated status (user-status)', - ['authenticated', 'anonymous'], - 'anonymous' - ), - hasContact: select( - 'Contact us button visibility (has-contact)', - ['true', 'false'], - 'true' - ), - selectedMenuItem: textNullable( - 'selected menu item (selected-menu-item)', - 'Docs' - ), - redirectPath: textNullable('redirect path (redirect-path)', ''), - authMethod: select( - 'auth method (auth-method)', - ['cookie', 'api'], - 'cookie' - ), - }), - }, - props: (() => { - // Lets `` load the nav links - const useMock = - inPercy() || new URLSearchParams(window.location.search).has('mock'); - return { - CloudMastheadComposite: { - navLinks: !useMock ? undefined : links, - }, - Other: { - useMock, - }, - }; - })(), - propsSet: { - default: { - CloudMastheadComposite: { - userStatus: 'anonymous', - hasContact: true, - selectedMenuItem: 'Docs', - redirectPath: '', - authMethod: 'cookie', - navLinks: links, - }, - }, - }, - }, -}; diff --git a/packages/web-components/src/components/masthead/__stories__/links.ts b/packages/web-components/src/components/masthead/__stories__/links.ts index 45716770aa3..75f7b0a763d 100644 --- a/packages/web-components/src/components/masthead/__stories__/links.ts +++ b/packages/web-components/src/components/masthead/__stories__/links.ts @@ -8,7 +8,6 @@ */ import { - MastheadLink, MastheadL1, MastheadLogoData, L0MenuItem, @@ -19,7 +18,7 @@ import { /** * Alternate logo */ -const logoData: MastheadLogoData = { +const mastheadLogoData: MastheadLogoData = { svg: ` Artboard @@ -468,3274 +467,7 @@ const mastheadL1Data: MastheadL1 = { }, }; -/** - * Masthead items. - */ -const mastheadLinks: MastheadLink[] = [ - { - title: 'Products', - titleEnglish: 'Products', - url: '', - hasMenu: true, - hasMegapanel: true, - megamenuLayout: 'tab', - menuSections: [ - { - heading: '', - menuItems: [ - { - title: 'Featured', - titleEnglish: 'Featured', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Featured', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ', - quickLinks: { - title: '', - links: [ - { - title: 'IBM Cloud Pak for Data', - titleEnglish: 'IBM Cloud Pak for Data', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Tools for data analysis, organization and management', - }, - { - title: 'IBM Cloud Pak for Security', - titleEnglish: 'IBM Cloud Pak for Security', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Security auditing, reporting, analysis and governance', - }, - { - title: 'IBM Cloud Pak for Business Automation', - titleEnglish: 'IBM Cloud Pak for Business Automation', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Operations management software with AI insights', - }, - { - title: 'IBM Cloud Pak for Integration', - titleEnglish: 'IBM Cloud Pak for Integration', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Tools to connect all of your apps, data and events', - }, - { - title: 'IBM Cloud Pak for Network Automation', - titleEnglish: 'IBM Cloud Pak for Network Automation', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Management software for telco network operations', - }, - { - title: 'IBM Cloud', - titleEnglish: 'IBM Cloud', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'IBM Z', - titleEnglish: 'IBM Z', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Analytics', - titleEnglish: 'Analytics', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Analytics', - headingUrl: 'https://www.ibm.com/placeholder', - description: 'Aggregate and analyze large datasets', - quickLinks: { - title: '', - links: [ - { - title: 'IBM Cloud Pak for Data', - titleEnglish: 'IBM Cloud Pak for Data', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Tools for data analysis, organization and management', - }, - { - title: 'Business Analytics Enterprise', - titleEnglish: 'Business Analytics Enterprise', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Cognos', - titleEnglish: 'Cognos', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'SPSS', - titleEnglish: 'SPSS', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'cplex', - titleEnglish: 'cplex', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Netezza', - titleEnglish: 'Netezza', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Watson Studio', - titleEnglish: 'Watson Studio', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: 'IDE to build, run and manage AI models', - }, - { - title: 'Planning Analytics', - titleEnglish: 'Planning Analytics', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Watson Discovery', - titleEnglish: 'Watson Discovery', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Search and analytics engine that adapts to custom domains', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Business Automation', - titleEnglish: 'Business Automation', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Business Automation', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - quickLinks: { - title: '', - links: [ - { - title: 'IBM Cloud Pak for Business Automation', - titleEnglish: 'IBM Cloud Pak for Business Automation', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Operations management software with AI insights', - }, - { - title: 'Watson Orchestrate', - titleEnglish: 'Watson Orchestrate', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'IBM RPA', - titleEnglish: 'IBM RPA', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'BlueWorks Live', - titleEnglish: 'BlueWorks Live', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'IBM Operational Decision Manager', - titleEnglish: 'IBM Operational Decision Manager', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'AI & ML', - titleEnglish: 'AI & ML', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'AI & ML', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Use Watson’s AI or build your own machine learning models', - quickLinks: { - title: '', - links: [ - { - title: 'IBM Cloud Pak for Data', - titleEnglish: 'IBM Cloud Pak for Data', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Tools for data analysis, organization and management', - }, - { - title: 'Watson Discovery', - titleEnglish: 'Watson Discovery', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Search and analytics engine that adapts to custom domains', - }, - { - title: 'Spech to Text', - titleEnglish: 'Spech to Text', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'API for real-time speech recognition and transcription', - }, - { - title: 'Text to Speech', - titleEnglish: 'Text to Speech', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: 'API for real-time text to speech conversion', - }, - { - title: 'IBM Cloud Pak for Data', - titleEnglish: 'IBM Cloud Pak for Data', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Tools for data analysis, organization and management', - }, - { - title: 'IBM Cloud Pak for AIOps', - titleEnglish: 'IBM Cloud Pak for AIOps', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'DevOps management tool with AI analysis and recommendations', - }, - { - title: 'IBM Watson Natural Language Understanding', - titleEnglish: 'IBM Watson Natural Language Understanding', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'API for text analysis and metadata extraction', - }, - { - title: 'Watson Studio', - titleEnglish: 'Watson Studio', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: 'IDE to build, run and manage AI models', - }, - { - title: 'IBM Watson Knowledge Catalog', - titleEnglish: 'IBM Watson Knowledge Catalog', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: 'SaaS for AI data management', - }, - { - title: 'Watson Assistant', - titleEnglish: 'Watson Assistant', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Compute & Servers', - titleEnglish: 'Compute & Servers', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Compute & Servers', - headingUrl: 'https://www.ibm.com/placeholder', - description: 'Run workloads on cloud infrastrcture', - quickLinks: { - title: '', - links: [ - { - title: 'IBM Z', - titleEnglish: 'IBM Z', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Power', - titleEnglish: 'Power', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Spectrum Computing', - titleEnglish: 'Spectrum Computing', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'LinuxONE', - titleEnglish: 'LinuxONE', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'IBM Cloud Bare Metal Servers', - titleEnglish: 'IBM Cloud Bare Metal Servers', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'IBM Cloud Virtual Servers', - titleEnglish: 'IBM Cloud Virtual Servers', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Database', - titleEnglish: 'Database', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Database', - headingUrl: 'https://www.ibm.com/placeholder', - description: 'Store, query and analyze structured data', - quickLinks: { - title: '', - links: [ - { - title: 'IBM Cloud Pak for Data', - titleEnglish: 'IBM Cloud Pak for Data', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Tools for data analysis, organization and management', - }, - { - title: 'IBM Informix on Cloud', - titleEnglish: 'IBM Informix on Cloud', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Managed DB for time series, spatial, NoSQL and SQL data', - }, - { - title: 'IBM Cloudant', - titleEnglish: 'IBM Cloudant', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Managed PCI-compliant JSON document store on CouchDB', - }, - { - title: 'IBM Cloud Database', - titleEnglish: 'IBM Cloud Database', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'IBM Cloud Hyper Protect DbaaS', - titleEnglish: 'IBM Cloud Hyper Protect DbaaS', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Managed PostgreSQL and MongoDB for sensitive data', - }, - { - title: 'IMS', - titleEnglish: 'IMS', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Tools for data analysis, organization and management', - }, - { - title: 'Db2', - titleEnglish: 'Db2', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'DevOps', - titleEnglish: 'DevOps', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'DevOps', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Manage infrastructure, environments and deployments', - quickLinks: { - title: '', - links: [ - { - title: 'IBM Cloud Pak for AIOps', - titleEnglish: 'IBM Cloud Pak for AIOps', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'IBM Cloud Continuous Delivery', - titleEnglish: 'IBM Cloud Continuous Delivery', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'UI and CLI based DevOps workflows based on Tekton Pipelines', - }, - { - title: 'IBM Cloud Schematics', - titleEnglish: 'IBM Cloud Schematics', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Managed service to provision resources with terraform templates', - }, - { - title: 'UrbanCode', - titleEnglish: 'UrbanCode', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'IT Automation', - titleEnglish: 'IT Automation', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'IT Automation', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - quickLinks: { - title: '', - links: [ - { - title: 'IBM Cloud Pak for AIOps', - titleEnglish: 'IBM Cloud Pak for AIOps', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'IBM Turbonomic', - titleEnglish: 'IBM Turbonomic', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Software to automate application resource management and optimize costs', - }, - { - title: 'IBM Instana', - titleEnglish: 'IBM Instana', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Middleware', - titleEnglish: 'Middleware', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Middleware', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - quickLinks: { - title: '', - links: [ - { - title: 'IBM Cloud Pak for Integration', - titleEnglish: 'IBM Cloud Pak for Integration', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Tools to connect all of your apps, data and events', - }, - { - title: 'MQ', - titleEnglish: 'MQ', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: 'Managed message broker', - }, - { - title: 'DataPower', - titleEnglish: 'DataPower', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'API Connect', - titleEnglish: 'API Connect', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'App Connect', - titleEnglish: 'App Connect', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Event Streams', - titleEnglish: 'Event Streams', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Aspera', - titleEnglish: 'Aspera', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'WebSphere Application Server', - titleEnglish: 'WebSphere Application Server', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: 'Runtime and SDK for Java applications', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Networking', - titleEnglish: 'Networking', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Networking', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'Cloud Pak for Network Automation', - titleEnglish: 'Cloud Pak for Network Automation', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Management software for telco network operations', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Operating Systems', - titleEnglish: 'Operating Systems', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Operating Systems', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'z/OS', - titleEnglish: 'z/OS', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'z/VSE', - titleEnglish: 'z/VSE', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'z/TPF', - titleEnglish: 'z/TPF', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'IBM i', - titleEnglish: 'IBM i', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Operations', - titleEnglish: 'Operations', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Operations', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - quickLinks: { - title: '', - links: [ - { - title: 'Maximo', - titleEnglish: 'Maximo', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'IBM Environmental Intelligence Suite', - titleEnglish: 'IBM Environmental Intelligence Suite', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Tririga', - titleEnglish: 'Tririga', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'IBM Sterling', - titleEnglish: 'IBM Sterling', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Supply Chain Intelligence Suite', - titleEnglish: 'Supply Chain Intelligence Suite', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'IBM Engineering Lifecycle Management', - titleEnglish: 'IBM Engineering Lifecycle Management', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Quantum', - titleEnglish: 'Quantum', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Quantum', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - quickLinks: { - title: '', - links: [ - { - title: 'IBM Quantum Systems', - titleEnglish: 'IBM Quantum Systems', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Qiskit runtime', - titleEnglish: 'Qiskit runtime', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'IBM Quantum Safe', - titleEnglish: 'IBM Quantum Safe', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Storage', - titleEnglish: 'Storage', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Storage', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'Spectrum', - titleEnglish: 'Spectrum', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Software for backup & recovery, SDS and analytics.', - }, - { - title: 'FlashSystem', - titleEnglish: 'FlashSystem', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Hybrid and all flash arrays for Block (SAN) storage', - }, - { - title: 'DS8900F', - titleEnglish: 'DS8900F', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: 'Storage for IBM Z and IBM Power Systems', - }, - { - title: 'Elastic Scale Storage', - titleEnglish: 'Elastic Scale Storage', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: 'Distributed file storage for big data and AI', - }, - { - title: 'Cloud Object Storage (On-premises)', - titleEnglish: 'Cloud Object Storage (On-premises)', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: 'Hyperscale object storage in the data center', - }, - { - title: 'SAN Volume Controller', - titleEnglish: 'SAN Volume Controller', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Storage virtualization for large scale workloads', - }, - { - title: 'SAN B-Type Switches', - titleEnglish: 'SAN B-Type Switches', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Support end-to-end NVMe with Gen 7 Fibre Channel', - }, - { - title: 'SAN C-Type Switches', - titleEnglish: 'SAN C-Type Switches', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'High-performance, multiprotocal storage networking', - }, - { - title: 'Tape System', - titleEnglish: 'Tape System', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: 'Tape libraries, cartridges and media', - }, - { - title: 'Cloud File Storage', - titleEnglish: 'Cloud File Storage', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Flash-backed, durable, fast and flexible NFS-based file storage', - }, - { - title: 'Cloud Block Storage', - titleEnglish: 'Cloud Block Storage', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Flash-backed, local disk performance with SAN persistence and durability', - }, - { - title: 'Cloud Object Storage', - titleEnglish: 'Cloud Object Storage', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Flexible, cost-effective and scalable cloud storage for unstructured data', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Security & Identity', - titleEnglish: 'Security & Identity', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Security & Identity', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'Trusteer', - titleEnglish: 'Trusteer', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Randori', - titleEnglish: 'Randori', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - target: 'external', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Verify', - titleEnglish: 'Verify', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'OpenPages with Watson', - titleEnglish: 'OpenPages with Watson', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'QRadar SIEM', - titleEnglish: 'QRadar SIEM', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Verify Privilege', - titleEnglish: 'Verify Privilege', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'MaaS360', - titleEnglish: 'MaaS360', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'QRadar SOAR', - titleEnglish: 'QRadar SOAR', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'zSecure', - titleEnglish: 'zSecure', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Guardium', - titleEnglish: 'Guardium', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'QRadar XDR Connect', - titleEnglish: 'QRadar XDR Connect', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'IBM Cloud Pak for Security', - titleEnglish: 'IBM Cloud Pak for Security', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Security auditing, reporting, analysis and governance', - }, - { - title: 'ReaQta', - titleEnglish: 'ReaQta', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'View all products', - titleEnglish: 'View all products', - url: 'https://www.ibm.com/products?lnk=hpmps_buall', - megaPanelViewAll: true, - }, - ], - }, - ], - }, - { - title: 'Solutions', - titleEnglish: 'Solutions', - url: '', - hasMenu: true, - hasMegapanel: true, - megamenuLayout: 'tab', - menuSections: [ - { - heading: '', - menuItems: [ - { - title: 'Automation', - titleEnglish: 'Automation', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Automation', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'Workflow', - titleEnglish: 'Workflow', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Enterprise Content Management', - titleEnglish: 'Enterprise Content Management', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Decision Management', - titleEnglish: 'Decision Management', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Tools for data analysis, organization and management', - }, - { - title: 'Application Performance Management', - titleEnglish: 'Application Performance Management', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Security auditing, reporting, analysis and governance', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Data & AI', - titleEnglish: 'Data & AI', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Data & AI', - headingUrl: 'https://www.ibm.com/placeholder', - description: 'Aggregate and analyze large datasets', - quickLinks: { - title: '', - links: [ - { - title: 'Data Fabric', - titleEnglish: 'Data Fabric', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'AI', - titleEnglish: 'AI', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Master Data Management', - titleEnglish: 'Master Data Management', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Tools for data analysis, organization and management', - }, - { - title: 'Data Lake', - titleEnglish: 'Data Lake', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Security auditing, reporting, analysis and governance', - }, - { - title: 'Data Warehouse', - titleEnglish: 'Data Warehouse', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Managed PostgreSQL and MongoDB for sensitive data', - }, - { - title: 'Customer Care', - titleEnglish: 'Customer Care', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Tools to connect all of your apps, data and events', - }, - { - title: 'Data Science', - titleEnglish: 'Data Science', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Operations management software with AI insights', - }, - { - title: 'Data Management', - titleEnglish: 'Data Management', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Management software for telco network operations', - }, - { - title: 'Data Quality', - titleEnglish: 'Data Quality', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Search and analytics engine that adapts to custom domains', - }, - { - title: 'Data Ops', - titleEnglish: 'Data Ops', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Hybrid Cloud', - titleEnglish: 'Hybrid Cloud', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Hybrid Cloud', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'Public Cloud', - titleEnglish: 'Public Cloud', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Private Cloud', - titleEnglish: 'Private Cloud', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Edge Computing', - titleEnglish: 'Edge Computing', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Hybrid Cloud Storage', - titleEnglish: 'Hybrid Cloud Storage', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Hybrid Cloud Management', - titleEnglish: 'Hybrid Cloud Management', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Infrastructure', - titleEnglish: 'Infrastructure', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Infrastructure', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'HPC', - titleEnglish: 'HPC', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Cloud Hosting', - titleEnglish: 'Cloud Hosting', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'IT Modernization', - titleEnglish: 'IT Modernization', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Tools for data analysis, organization and management', - }, - { - title: 'Data protection', - titleEnglish: 'Data protection', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Security auditing, reporting, analysis and governance', - }, - { - title: 'Confidential Computing', - titleEnglish: 'Confidential Computing', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Managed PostgreSQL and MongoDB for sensitive data', - }, - { - title: 'Backup and Recovery', - titleEnglish: 'Backup and Recovery', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Archivex', - titleEnglish: 'Archivex', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Industry', - titleEnglish: 'Industry', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Industry', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'Aerospace', - titleEnglish: 'Aerospace', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Airline industry', - titleEnglish: 'Airline industry', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Automotive', - titleEnglish: 'Automotive', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Banking and finance', - titleEnglish: 'Banking and finance', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Consumer goods', - titleEnglish: 'Consumer goods', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Education', - titleEnglish: 'Education', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Electronics industry', - titleEnglish: 'Electronics industry', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Energy and utilities', - titleEnglish: 'Energy and utilities', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Federal', - titleEnglish: 'Federal', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Financial services', - titleEnglish: 'Financial services', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Freight and logistics industry', - titleEnglish: 'Freight and logistics industry', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Government', - titleEnglish: 'Government', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Healthcare', - titleEnglish: 'Healthcare', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Hotel industry', - titleEnglish: 'Hotel industry', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Insurance', - titleEnglish: 'Insurance', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Life sciences', - titleEnglish: 'Life sciences', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Manufacturing', - titleEnglish: 'Manufacturing', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Media and entertainment', - titleEnglish: 'Media and entertainment', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Partners & Applications', - titleEnglish: 'Partners & Applications', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Partners & Applications', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'SAP', - titleEnglish: 'SAP', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'VMware', - titleEnglish: 'VMware', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'AWS', - titleEnglish: 'AWS', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'GCP', - titleEnglish: 'GCP', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Azure', - titleEnglish: 'Azure', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Salesforce', - titleEnglish: 'Salesforce', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Adobe', - titleEnglish: 'Adobe', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Nvidia', - titleEnglish: 'Nvidia', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Security', - titleEnglish: 'Security', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Security', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'Zero Trust', - titleEnglish: 'Zero Trust', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Data Security', - titleEnglish: 'Data Security', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Security auditing, reporting, analysis and governance', - }, - { - title: 'XDR', - titleEnglish: 'XDR', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Data Security', - titleEnglish: 'Data Security', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Security auditing, reporting, analysis and governance', - }, - { - title: 'Cloud Security', - titleEnglish: 'Cloud Security', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Managed PostgreSQL and MongoDB for sensitive data', - }, - { - title: 'Security Services', - titleEnglish: 'Security Services', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Ransomware', - titleEnglish: 'Ransomware', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Operations management software with AI insights', - }, - { - title: 'Insider Threat', - titleEnglish: 'Insider Threat', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Management software for telco network operations', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Supply Chain', - titleEnglish: 'Supply Chain', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Supply Chain', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'Visibility', - titleEnglish: 'Visibility', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'EDI', - titleEnglish: 'EDI', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Blockchain', - titleEnglish: 'Blockchain', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Data Exchange', - titleEnglish: 'Data Exchange', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Supply Chain Services', - titleEnglish: 'Supply Chain Services', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Sustainable Supply Chains', - titleEnglish: 'Sustainable Supply Chains', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Sustainability', - titleEnglish: 'Sustainability', - url: 'https://www.ibm.com/placeholder', - highlighted: true, - megapanelContent: { - headingTitle: 'Sustainability', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'Asset Management', - titleEnglish: 'Asset Management', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Operations management software with AI insights', - }, - { - title: 'Facilities Management', - titleEnglish: 'Facilities Management', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Carbon Peformance Engine', - titleEnglish: 'Carbon Peformance Engine', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Regenerative Agriculture', - titleEnglish: 'Regenerative Agriculture', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Renewables Forecasting', - titleEnglish: 'Renewables Forecasting', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Vegetation Management', - titleEnglish: 'Vegetation Management', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'IT Sustainability', - titleEnglish: 'IT Sustainability', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'Sustainable Supply Chains', - titleEnglish: 'Sustainable Supply Chains', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - { - title: 'ESG Reporting', - titleEnglish: 'ESG Reporting', - highlightedLink: false, - url: 'https://www.ibm.com/placeholder', - description: - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ac', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - ], - }, - ], - }, - { - title: 'Consulting', - titleEnglish: 'Consulting', - url: '', - hasMenu: true, - hasMegapanel: true, - megamenuLayout: 'tab', - menuSections: [ - { - heading: '', - menuItems: [ - { - title: 'Overview', - titleEnglish: 'Overview', - url: 'https://www.ibm.com/consulting?lnk=hpmco&lnk2=link', - megapanelContent: { - headingTitle: 'IBM Consulting', - headingUrl: 'https://www.ibm.com/consulting?lnk=hpmco&lnk2=link', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'IBM iX', - titleEnglish: 'IBM iX', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Garage', - titleEnglish: 'Garage', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'X-Force', - titleEnglish: 'X-Force', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'TSS', - titleEnglish: 'TSS', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Lab Services', - titleEnglish: 'Lab Services', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Investments', - titleEnglish: 'Investments', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Announcements', - titleEnglish: 'Announcements', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Client Success', - titleEnglish: 'Client Success', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Careers', - titleEnglish: 'Careers', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Cloud', - titleEnglish: 'Cloud', - url: 'https://www.ibm.com/placeholder', - megapanelContent: { - headingTitle: 'Cloud', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'Cloud Strategy', - titleEnglish: 'Cloud Strategy', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Hybrid Cloud', - titleEnglish: 'Hybrid Cloud', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Cloud Migration', - titleEnglish: 'Cloud Migration', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Multicloud', - titleEnglish: 'Multicloud', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Cloud Architecture', - titleEnglish: 'Cloud Architecture', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Managed Cloud Services', - titleEnglish: 'Managed Cloud Services', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Data & Apps', - titleEnglish: 'Data & Apps', - url: 'https://www.ibm.com/placeholder', - megapanelContent: { - headingTitle: 'Data & Apps', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'Data and Analytics', - titleEnglish: 'Data and Analytics', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'AI', - titleEnglish: 'AI', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Application Services', - titleEnglish: 'Application Services', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Application Development', - titleEnglish: 'Application Development', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Application Modernization', - titleEnglish: 'Application Modernization', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Mobile', - titleEnglish: 'Mobile', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Application Security', - titleEnglish: 'Application Security', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Experience', - titleEnglish: 'Experience', - url: 'https://www.ibm.com/placeholder', - megapanelContent: { - headingTitle: 'Experience', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'Customer Experience', - titleEnglish: 'Customer Experience', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'E-commerce', - titleEnglish: 'E-commerce', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Payments', - titleEnglish: 'Payments', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Operations', - titleEnglish: 'Operations', - url: 'https://www.ibm.com/placeholder', - megapanelContent: { - headingTitle: 'Operations', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'Outsourcing', - titleEnglish: 'Outsourcing', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Procurement & Strategic Sourcing', - titleEnglish: 'Procurement & Strategic Sourcing', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Supply Chain', - titleEnglish: 'Supply Chain', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Finance', - titleEnglish: 'Finance', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Marketing', - titleEnglish: 'Marketing', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Talent', - titleEnglish: 'Talent', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Finance', - titleEnglish: 'Finance', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Business Process Reengineering', - titleEnglish: 'Business Process Reengineering', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Security', - titleEnglish: 'Security', - url: 'https://www.ibm.com/placeholder', - megapanelContent: { - headingTitle: 'Security', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'Security Strategy', - titleEnglish: 'Security Strategy', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Cloud', - titleEnglish: 'Cloud', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Threat managment', - titleEnglish: 'Threat managment', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'GRC', - titleEnglish: 'GRC', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Data', - titleEnglish: 'Data', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Threat intelligence', - titleEnglish: 'Threat intelligence', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Risk Management', - titleEnglish: 'Risk Management', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Applications', - titleEnglish: 'Applications', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Virtual SOC', - titleEnglish: 'Virtual SOC', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Offensive Security Services', - titleEnglish: 'Offensive Security Services', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Identity and Access', - titleEnglish: 'Identity and Access', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Managed Detection and Response', - titleEnglish: 'Managed Detection and Response', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Penetration Testing', - titleEnglish: 'Penetration Testing', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Managed Security Services', - titleEnglish: 'Managed Security Services', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Adversary Simulation', - titleEnglish: 'Adversary Simulation', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Managed Infrastructure and Endpoint Security', - titleEnglish: - 'Managed Infrastructure and Endpoint Security', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Strategy', - titleEnglish: 'Strategy', - url: 'https://www.ibm.com/placeholder', - megapanelContent: { - headingTitle: 'Strategy', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'Business Strategy', - titleEnglish: 'Business Strategy', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Sustainability', - titleEnglish: 'Sustainability', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'GRC', - titleEnglish: 'GRC', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Risk Management', - titleEnglish: 'Risk Management', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Partners', - titleEnglish: 'Partners', - url: 'https://www.ibm.com/placeholder', - megapanelContent: { - headingTitle: 'Partners', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'SAP', - titleEnglish: 'SAP', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Adobe', - titleEnglish: 'Adobe', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'AWS', - titleEnglish: 'AWS', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Red Hat', - titleEnglish: 'Red Hat', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'SalesForce', - titleEnglish: 'SalesForce', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'ServiceNow', - titleEnglish: 'ServiceNow', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Microsoft', - titleEnglish: 'Microsoft', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Workday', - titleEnglish: 'Workday', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Celonis', - titleEnglish: 'Celonis', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Oracle', - titleEnglish: 'Oracle', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Insights', - titleEnglish: 'Insights', - url: 'https://www.ibm.com/placeholder', - megapanelContent: { - headingTitle: 'Insights', - headingUrl: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - quickLinks: { - title: '', - links: [ - { - title: 'IBV', - titleEnglish: 'IBV', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Cost of a Data Breach', - titleEnglish: 'Cost of a Data Breach', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'X-Force Threat Intelligence', - titleEnglish: 'X-Force Threat Intelligence', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Hybrid Cloud Insight', - titleEnglish: 'Hybrid Cloud Insight', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'AI Insight', - titleEnglish: 'AI Insight', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Sustainability Insight', - titleEnglish: 'Sustainability Insight', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Customer Experience Insight', - titleEnglish: 'Customer Experience Insight', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - { - title: 'Supply Chain Insight', - titleEnglish: 'Supply Chain Insight', - url: 'https://www.ibm.com/placeholder', - description: - 'Description text Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - ], - }, - ], - }, - { - title: 'Support', - titleEnglish: 'Support', - url: '', - hasMenu: true, - hasMegapanel: true, - megamenuLayout: 'list', - menuSections: [ - { - heading: '', - menuItems: [ - { - title: 'What is...', - titleEnglish: 'What is...', - url: 'https://www.ibm.com/cloud/learn?lnk=hpmls_buwi', - megapanelContent: { - headingTitle: 'What is...', - headingUrl: 'https://www.ibm.com/cloud/learn?lnk=hpmls_buwi', - description: '', - quickLinks: { - title: '', - links: [ - { - title: 'Artificial intelligence', - titleEnglish: 'Artificial intelligence', - url: 'https://www.ibm.com/cloud/learn/what-is-artificial-intelligence?lnk=hpmls_buwi', - }, - { - title: 'Automation', - titleEnglish: 'Automation', - url: 'https://www.ibm.com/topics/automation?lnk=hpmls_buwi', - }, - { - title: 'Blockchain', - titleEnglish: 'Blockchain', - url: 'https://www.ibm.com/topics/what-is-blockchain?lnk=hpmls_buwi', - }, - { - title: 'Business intelligence', - titleEnglish: 'Business intelligence', - url: 'https://www.ibm.com/topics/business-intelligence?lnk=hpmls_buwi', - }, - { - title: 'Chatbots', - titleEnglish: 'Chatbots', - url: 'https://www.ibm.com/cloud/learn/chatbots-explained?lnk=hpmls_buwi', - }, - { - title: 'Cloud computing', - titleEnglish: 'Cloud computing', - url: 'https://www.ibm.com/cloud/learn/cloud-computing?lnk=hpmls_buwi', - }, - { - title: 'Containerization', - titleEnglish: 'Containerization', - url: 'https://www.ibm.com/cloud/container-service?lnk=hpmls_buwi', - }, - { - title: 'Cybersecurity', - titleEnglish: 'Cybersecurity', - url: 'https://www.ibm.com/topics/cybersecurity?lnk=hpmls_buwi', - }, - { - title: 'Databases', - titleEnglish: 'Databases', - url: 'https://www.ibm.com/cloud/learn/database?lnk=hpmls_buwi', - }, - { - title: 'DevOps', - titleEnglish: 'DevOps', - url: 'https://www.ibm.com/cloud/learn/devops-a-complete-guide?lnk=hpmls_buwi', - }, - { - title: 'Hybrid Cloud', - titleEnglish: 'Hybrid Cloud', - url: 'https://www.ibm.com/cloud/learn/hybrid-cloud?lnk=hpmls_buwi', - }, - { - title: 'Kubernetes', - titleEnglish: 'Kubernetes', - url: 'https://www.ibm.com/cloud/learn/kubernetes?lnk=hpmls_buwi', - }, - { - title: 'Quantum computing', - titleEnglish: 'Quantum computing', - url: 'https://www.ibm.com/quantum-computing/learn/what-is-quantum-computing?lnk=hpmls_buwi', - }, - { - title: 'Supply chain', - titleEnglish: 'Supply chain', - url: 'https://www.ibm.com/topics/supply-chain-management?lnk=hpmls_buwi', - }, - ], - }, - feature: { - heading: '', - imageUrl: - 'https://1.dam.s81c.com/m/581adf40f2b008ec/original/megamenu-pictogram-what-is-_.png', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Training', - titleEnglish: 'Training', - url: 'https://www.ibm.com/training/?lnk=hpmls_butr', - megapanelContent: { - headingTitle: 'Training', - headingUrl: 'https://www.ibm.com/training/?lnk=hpmls_butr', - description: '', - quickLinks: { - title: '', - links: [ - { - title: 'Courses', - titleEnglish: 'Courses', - url: 'https://www.ibm.com/training/search?q=course&lnk=hpmls_butr', - }, - { - title: 'Learning journeys', - titleEnglish: 'Learning journeys', - url: 'https://www.ibm.com/training/journeys?lnk=hpmls_butr', - }, - { - title: 'Professional certifications', - titleEnglish: 'Professional certifications', - url: 'https://www.ibm.com/certify?lnk=hpmls_butr', - }, - { - title: 'Digital learning subscriptions', - titleEnglish: 'Digital learning subscriptions', - url: 'https://www.ibm.com/training/subscriptions?lnk=hpmls_butr', - }, - ], - }, - feature: { - heading: '', - imageUrl: - 'https://1.dam.s81c.com/m/5540e5627aeb2568/original/megamenu-pictogram-training.png', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Developer education', - titleEnglish: 'Developer education', - url: 'https://developer.ibm.com/?lnk=hpmls_bude', - megapanelContent: { - headingTitle: 'Developer education', - headingUrl: 'https://developer.ibm.com/?lnk=hpmls_bude', - description: '', - quickLinks: { - title: '', - links: [ - { - title: 'Code patterns', - titleEnglish: 'Code patterns', - url: 'https://developer.ibm.com/patterns/?lnk=hpmls_bude', - }, - { - title: 'Developer community', - titleEnglish: 'Developer community', - url: 'https://developer.ibm.com/community/?lnk=hpmls_bude', - }, - { - title: 'Developer events', - titleEnglish: 'Developer events', - url: 'https://developer.ibm.com/events/?lnk=hpmls_bude', - }, - { - title: 'Open Source @ IBM', - titleEnglish: 'Open Source @ IBM', - url: 'https://ibm.com/opensource?lnk=hpmls_bude', - }, - { - title: 'Technical articles', - titleEnglish: 'Technical articles', - url: 'https://developer.ibm.com/articles?lnk=hpmls_bude', - }, - { - title: 'Tutorials', - titleEnglish: 'Tutorials', - url: 'https://developer.ibm.com/tutorials/?lnk=hpmls_bude', - }, - { - title: 'Videos', - titleEnglish: 'Videos', - url: 'https://developer.ibm.com/videos?lnk=hpmls_bude', - }, - { - title: 'View more Developer education', - titleEnglish: 'View more Developer education', - url: 'https://developer.ibm.com/?lnk=hpmls_bude', - }, - ], - }, - feature: { - heading: '', - imageUrl: - 'https://1.dam.s81c.com/m/1e651d0f7b539774/original/megamenu-pictogram-developer-education.png', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Documentation', - titleEnglish: 'Documentation', - url: 'https://www.ibm.com/docs/en?lnk=hpmls_budc', - megapanelContent: { - headingTitle: 'Documentation', - headingUrl: 'https://www.ibm.com/docs/en?lnk=hpmls_budc', - description: '', - quickLinks: { - title: '', - links: [ - { - title: 'All product documentation', - titleEnglish: 'All product documentation', - url: 'https://www.ibm.com/docs/en?lnk=hpmls_budc', - }, - { - title: 'For products on IBM Cloud', - titleEnglish: 'For products on IBM Cloud', - url: 'https://cloud.ibm.com/docs?lnk=hpmls_budc', - }, - { - title: 'For use cases — IBM Redbooks', - titleEnglish: 'For use cases — IBM Redbooks', - url: 'https://www.redbooks.ibm.com/?lnk=hpmls_budc', - }, - ], - }, - feature: { - heading: '', - imageUrl: - 'https://1.dam.s81c.com/m/49d529fab45bb565/original/megamenu-pictogram-documentation.png', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Community', - titleEnglish: 'Community', - url: '', - megapanelContent: { - headingTitle: 'Community', - headingUrl: '', - description: '', - quickLinks: { - title: '', - links: [ - { - title: 'IBM Developer', - titleEnglish: 'IBM Developer', - url: 'https://developer.ibm.com/?lnk=hpmls_buco', - }, - { - title: 'IBM Community', - titleEnglish: 'IBM Community', - url: 'https://community.ibm.com/community/user/home?lnk=hpmls_buco', - }, - { - title: 'Support forums', - titleEnglish: 'Support forums', - url: 'https://www.ibm.com/mysupport/s/forumshome?lnk=hpmls_buco', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Resources', - titleEnglish: 'Resources', - url: 'https://www.ibm.com/blogs/?lnk=hpmls_bure', - megapanelContent: { - headingTitle: 'Resources', - headingUrl: 'https://www.ibm.com/blogs/?lnk=hpmls_bure', - description: '', - quickLinks: { - title: '', - links: [ - { - title: 'Blogs & thought leadership', - titleEnglish: 'Blogs & thought leadership', - url: 'https://www.ibm.com/blogs/?lnk=hpmls_bure', - }, - { - title: 'Case studies & client stories', - titleEnglish: 'Case studies & client stories', - url: 'https://www.ibm.com/case-studies?lnk=hpmls_bure', - }, - { - title: 'Upcoming events & webinars', - titleEnglish: 'Upcoming events & webinars', - url: 'https://www.ibm.com/events?lnk=hpmls_bure', - }, - { - title: 'IBM Institute for Business Value', - titleEnglish: 'IBM Institute for Business Value', - url: 'https://www.ibm.com/thought-leadership/institute-business-value?lnk=hpmls_bure', - }, - { - title: 'Licensing & compliance', - titleEnglish: 'Licensing & compliance', - url: 'https://www.ibm.com/about/software-licensing/?lnk=hpmls_bure', - }, - ], - }, - feature: { - heading: '', - imageUrl: - 'https://1.dam.s81c.com/m/164ef3660bad78a8/original/megamenu-pictogram-resources.png', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Support', - titleEnglish: 'Support', - url: 'https://www.ibm.com/mysupport?lnk=hpmls_busu', - megapanelContent: { - headingTitle: 'Support', - headingUrl: 'https://www.ibm.com/mysupport?lnk=hpmls_busu', - description: '', - quickLinks: { - title: '', - links: [ - { - title: 'Download fixes, updates & drivers', - titleEnglish: 'Download fixes, updates & drivers', - url: 'https://www.ibm.com/support/fixcentral/?lnk=hpmls_busu', - }, - { - title: 'Download licensed software - Passport Advantage', - titleEnglish: - 'Download licensed software - Passport Advantage', - url: 'https://www.ibm.com/software/passportadvantage/pao_customer.html?lnk=hpmls_busu', - }, - { - title: 'View your cases', - titleEnglish: 'View your cases', - url: 'https://www.ibm.com/mysupport/s/my-cases?lnk=hpmls_busu', - }, - { - title: 'Open a case', - titleEnglish: 'Open a case', - url: 'https://www.ibm.com/mysupport/s/redirecttoopencasepage?lnk=hpmls_busu', - }, - { - title: 'View available support plans', - titleEnglish: 'View available support plans', - url: 'https://www.ibm.com/support/offerings?lnk=hpmls_busu', - }, - { - title: 'View more on Support', - titleEnglish: 'View more on Support', - url: 'https://www.ibm.com/mysupport?lnk=hpmls_busu&lnk2=all', - }, - ], - }, - feature: { - heading: '', - imageUrl: - 'https://1.dam.s81c.com/m/5b1abed637b01b55/original/megamenu-pictogram-support.png', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Cloud platform support', - titleEnglish: 'Cloud platform support', - url: 'https://www.ibm.com/cloud/support?lnk=hpmls_bucl', - }, - { - title: 'Newsletter subscriptions', - titleEnglish: 'Newsletter subscriptions', - url: 'https://www.ibm.com/subscribe/', - }, - ], - }, - ], - }, - { - title: 'More', - titleEnglish: 'More', - url: '', - hasMenu: true, - hasMegapanel: true, - megamenuLayout: 'list', - menuSections: [ - { - heading: '', - menuItems: [ - { - title: 'Partner with us', - titleEnglish: 'Partners', - url: 'https://www.ibm.com/partners?lnk=hpmex_bupa', - megapanelContent: { - headingTitle: 'Partner with us', - headingUrl: 'https://www.ibm.com/partners?lnk=hpmex_bupa', - description: '', - quickLinks: { - title: '', - links: [ - { - title: 'PartnerWorld', - titleEnglish: 'Partner with us — PartnerWorld', - url: 'https://www.ibm.com/partnerworld/public?lnk=hpmex_bupa', - }, - { - title: 'Our strategic partnerships', - titleEnglish: 'Our strategic partnerships', - url: 'https://www.ibm.com/alliances?lnk=hpmex_bupa', - }, - { - title: 'Flexible payment plans', - titleEnglish: 'Flexible payment plans', - url: 'https://www.ibm.com/partnerworld/financing?lnk=hpmex_bupa', - }, - ], - }, - feature: { - heading: '', - imageUrl: - 'https://1.dam.s81c.com/m/4075a8633a1137d/original/megamenu-pictogram-partners.png', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'IBM Research', - titleEnglish: 'IBM Research', - url: 'https://research.ibm.com?lnk=hpmex_bure', - megapanelContent: { - headingTitle: 'IBM Research', - headingUrl: 'https://research.ibm.com?lnk=hpmex_bure', - description: '', - quickLinks: { - title: '', - links: [ - { - title: 'Blog', - titleEnglish: 'Blog', - url: 'https://research.ibm.com/blog?lnk=hpmex_bure', - }, - { - title: 'Publications', - titleEnglish: 'Publications', - url: 'https://research.ibm.com/publications?lnk=hpmex_bure', - }, - { - title: 'Teams', - titleEnglish: 'Teams', - url: 'https://research.ibm.com/teams?lnk=hpmex_bure', - }, - { - title: 'Collaborate with us', - titleEnglish: 'Collaborate with us', - url: 'https://research.ibm.com/collaborate?lnk=hpmex_bure', - }, - ], - }, - feature: { - heading: '', - imageUrl: - 'https://1.dam.s81c.com/m/5e05b0b234bc3846/original/megamenu-pictogram-ibm-research.png', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'About IBM', - titleEnglish: 'About IBM', - url: 'https://www.ibm.com/about?lnk=hpmex_buab', - megapanelContent: { - headingTitle: 'About IBM', - headingUrl: 'https://www.ibm.com/about?lnk=hpmex_buab', - description: '', - quickLinks: { - title: '', - links: [ - { - title: 'Annual report', - titleEnglish: 'Annual report', - url: 'https://www.ibm.com/annualreport/?lnk=hpmex_buab', - }, - { - title: 'Career opportunities', - titleEnglish: 'Career opportunities', - url: 'https://www.ibm.com/employment/?lnk=hpmex_buab', - }, - { - title: 'Corporate social responsibility', - titleEnglish: 'Corporate social responsibility', - url: 'https://www.ibm.org?lnk=hpmex_buab', - }, - { - title: 'Diversity & inclusion', - titleEnglish: 'Diversity & inclusion', - url: 'https://www.ibm.com/employment/inclusion/?lnk=hpmex_buab', - }, - { - title: 'Industry analyst reports', - titleEnglish: 'Industry analyst reports', - url: 'https://www.ibm.com/reports/analyst/?lnk=hpmex_buab', - }, - { - title: 'Investor relations', - titleEnglish: 'Investor relations', - url: 'https://www.ibm.com/investor/?lnk=hpmex_buab', - }, - { - title: 'Licensing & compliance', - titleEnglish: 'Licensing & compliance', - url: 'https://www.ibm.com/about/software-licensing/?lnk=hpmex_buab', - }, - { - title: 'News & announcements', - titleEnglish: 'News & announcements', - url: 'https://newsroom.ibm.com?lnk=hpmex_buab', - }, - { - title: 'Thought leadership', - titleEnglish: 'Thought leadership', - url: 'https://www.ibm.com/thought-leadership/?lnk=hpmex_buab', - }, - { - title: 'Security, privacy & trust', - titleEnglish: 'Security, privacy & trust', - url: 'https://www.ibm.com/trust?lnk=hpmex_buab', - }, - ], - }, - feature: { - heading: '', - imageUrl: - 'https://1.dam.s81c.com/m/220eb8ea8345a4d6/original/megamenu-pictogram-about-ibm.png', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'COVID-19', - titleEnglish: 'COVID-19', - url: 'https://www.ibm.com/impact/covid-19?lnk=hpmex_buco', - megapanelContent: { - headingTitle: 'COVID-19', - headingUrl: 'https://www.ibm.com/impact/covid-19?lnk=hpmex_buco', - description: '', - quickLinks: { - title: '', - links: [ - { - title: 'Business solutions', - titleEnglish: 'Business solutions', - url: 'https://www.ibm.com/impact/covid-19/business-solutions?lnk=hpmex_buco', - }, - { - title: 'Action guide', - titleEnglish: 'Action guide', - url: 'https://www.ibm.com/thought-leadership/institute-business-value/report/covid-19-action-guide?lnk=hpmex_buco', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - ], - }, - ], - }, -]; - -const mastheadLinksV2: L0MenuItem[] = [ +const mastheadL0Data: L0MenuItem[] = [ { title: 'Faceted Megamenu', titleEnglish: 'Faceted Megamenu', @@ -5450,644 +2182,11 @@ const mastheadLinksV2: L0MenuItem[] = [ }, { title: 'Basic Link', - titleEnglish: 'Demo Simple', + titleEnglish: 'Basic Link', url: 'https://www.example.com', }, ]; -/** - * Custom masthead link items. - */ -const customLinks: MastheadLink[] = [ - { - title: 'Products & Solutions', - titleEnglish: 'Products & Solutions', - url: '', - hasMenu: true, - hasMegapanel: true, - menuSections: [ - { - heading: 'The essentials', - menuItems: [ - { - title: 'Hybrid Cloud', - titleEnglish: 'Hybrid Cloud', - url: '', - highlighted: true, - megapanelContent: { - headingTitle: 'Hybrid Cloud', - headingUrl: '', - description: - 'Blend cloud and on-premises resources for flexibility and balance', - quickLinks: { - title: '', - links: [ - { - title: 'What is Hybrid Cloud?', - titleEnglish: 'What is Hybrid Cloud?', - highlightedLink: true, - url: 'https://www.ibm.com/cloud/learn/hybrid-cloud?lnk=hpmps_ess', - }, - { - title: 'Hybrid Cloud solutions', - titleEnglish: 'Hybrid Cloud solutions', - highlightedLink: true, - url: 'https://www.ibm.com/cloud/go-hybrid?lnk=hpmps_ess', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Artificial intelligence', - titleEnglish: 'Artificial intelligence', - url: '', - highlighted: true, - megapanelContent: { - headingTitle: 'Artificial intelligence', - headingUrl: '', - description: 'Unlock the value in your organization with Watson', - quickLinks: { - title: '', - links: [ - { - title: 'What is AI?', - titleEnglish: 'What is AI?', - highlightedLink: true, - url: 'https://www.ibm.com/cloud/learn/artificial-intelligence?lnk=hpmps_ess', - }, - { - title: 'AI solutions', - titleEnglish: 'AI solutions', - highlightedLink: true, - url: 'https://www.ibm.com/cloud/ai?lnk=hpmps_ess', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Top products & platforms', - titleEnglish: 'Top products & platforms', - url: 'https://www.ibm.com/products?lnk=hpmps_bupr', - megapanelContent: { - headingTitle: 'Top products & platforms', - headingUrl: 'https://www.ibm.com/products?lnk=hpmps_bupr', - description: '', - quickLinks: { - title: '', - links: [ - { - title: 'Aspera', - titleEnglish: 'Aspera', - url: 'https://www.ibm.com/products/aspera?lnk=hpmps_bupr', - }, - { - title: 'Cognos', - titleEnglish: 'Cognos', - url: 'https://www.ibm.com/products/cognos-analytics?lnk=hpmps_bupr', - }, - { - title: 'Db2', - titleEnglish: 'Db2', - url: 'https://www.ibm.com/analytics/db2?lnk=hpmps_bupr', - }, - { - title: 'IBM Cloud', - titleEnglish: 'IBM Cloud', - url: 'https://www.ibm.com/cloud?lnk=hpmps_bupr', - }, - { - title: 'IBM Cloud Paks', - titleEnglish: 'IBM Cloud Paks', - url: 'https://www.ibm.com/cloud/paks?lnk=hpmps_bupr', - }, - { - title: 'IBM Sterling', - titleEnglish: 'IBM Sterling', - url: 'https://www.ibm.com/supply-chain/sterling?lnk=hpmps_bupr', - }, - { - title: 'IBM Z', - titleEnglish: 'IBM Z', - url: 'https://www.ibm.com/it-infrastructure/z?lnk=hpmps_bupr', - }, - { - title: 'Red Hat OpenShift', - titleEnglish: 'Red Hat OpenShift', - url: 'https://www.ibm.com/cloud/openshift?lnk=hpmps_bupr', - }, - { - title: 'SPSS Statistics', - titleEnglish: 'SPSS Statistics', - url: 'https://www.ibm.com/products/spss-statistics?lnk=hpmps_bupr', - }, - { - title: 'Watson', - titleEnglish: 'Watson', - url: 'https://www.ibm.com/watson?lnk=hpmps_bupr', - }, - { - title: 'WebSphere', - titleEnglish: 'WebSphere', - url: 'https://www.ibm.com/cloud/websphere-application-server?lnk=hpmps_bupr', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Solutions', - titleEnglish: 'Solutions', - url: '', - megapanelContent: { - headingTitle: 'Solutions', - headingUrl: '', - description: '', - quickLinks: { - title: '', - links: [ - { - title: 'Artificial intelligence', - titleEnglish: 'Artificial intelligence', - url: 'https://www.ibm.com/cloud/ai?lnk=hpmps_buai', - }, - { - title: 'Blockchain', - titleEnglish: 'Blockchain', - url: 'https://www.ibm.com/blockchain?lnk=hpmps_bubc', - }, - { - title: 'Business automation', - titleEnglish: 'Business automation', - url: 'https://www.ibm.com/cloud/automation?lnk=hpmps_buau', - }, - { - title: 'Business operations', - titleEnglish: 'Business operations', - url: 'https://www.ibm.com/business-operations?lnk=hpmps_buop', - }, - { - title: 'Cloud computing', - titleEnglish: 'Cloud computing', - url: 'https://www.ibm.com/cloud?lnk=hpmps_bucl', - }, - { - title: 'Data & Analytics', - titleEnglish: 'Data & Analytics', - url: 'https://www.ibm.com/analytics?lnk=hpmps_buda', - }, - { - title: 'Hybrid Cloud', - titleEnglish: 'Hybrid Cloud', - url: 'https://www.ibm.com/cloud/hybrid?lnk=hpmps_bucl', - }, - { - title: 'IT infrastructure', - titleEnglish: 'IT infrastructure', - url: 'https://www.ibm.com/it-infrastructure?lnk=hpmps_buit', - }, - { - title: 'Quantum computing', - titleEnglish: 'Quantum computing', - url: 'https://www.ibm.com/quantum-computing/?lnk=hpmps_qc', - }, - { - title: 'Security', - titleEnglish: 'Security', - url: 'https://www.ibm.com/security?lnk=hpmps_buse', - }, - { - title: 'Supply chain', - titleEnglish: 'Supply chain', - url: 'https://www.ibm.com/supply-chain?lnk=hpmps_busc', - }, - { - title: 'COVID-19 solutions', - titleEnglish: 'COVID-19 solutions', - url: 'https://www.ibm.com/impact/covid-19/business-solutions?lnk=hpmps_buco', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'Industries', - titleEnglish: 'Industries', - url: 'https://www.ibm.com/industries?lnk=hpmps_buin', - megapanelContent: { - headingTitle: 'Industries', - headingUrl: 'https://www.ibm.com/industries?lnk=hpmps_buin', - description: '', - quickLinks: { - title: '', - links: [ - { - title: 'Aerospace & defense', - titleEnglish: 'Aerospace & defense', - url: 'https://www.ibm.com/industries/aerospace-defense?lnk=hpmps_buin', - }, - { - title: 'Automotive', - titleEnglish: 'Automotive', - url: 'https://www.ibm.com/industries/automotive?lnk=hpmps_buin', - }, - { - title: 'Banking & financial markets', - titleEnglish: 'Banking & financial markets', - url: 'https://www.ibm.com/industries/banking-financial-markets?lnk=hpmps_buin', - }, - { - title: 'Education', - titleEnglish: 'Education', - url: 'https://www.ibm.com/industries/education?lnk=hpmps_buin', - }, - { - title: 'Electronics', - titleEnglish: 'Electronics', - url: 'https://www.ibm.com/industries/electronics?lnk=hpmps_buin', - }, - { - title: 'Energy & utilities', - titleEnglish: 'Energy & utilities', - url: 'https://www.ibm.com/industries/energy?lnk=hpmps_buin', - }, - { - title: 'Government', - titleEnglish: 'Government', - url: 'https://www.ibm.com/industries/government?lnk=hpmps_buin', - }, - { - title: 'Healthcare', - titleEnglish: 'Healthcare', - url: 'https://www.ibm.com/industries/healthcare?lnk=hpmps_buin', - }, - { - title: 'Insurance', - titleEnglish: 'Insurance', - url: 'https://www.ibm.com/industries/insurance?lnk=hpmps_buin', - }, - { - title: 'Life sciences', - titleEnglish: 'Life sciences', - url: 'https://www.ibm.com/industries/lifesciences?lnk=hpmps_buin', - }, - { - title: 'View all Industries', - titleEnglish: 'View all Industries', - url: 'https://www.ibm.com/industries?lnk=hpmps_buin#2546397', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - { - title: 'View all products', - titleEnglish: 'View all products', - url: 'https://www.ibm.com/products?lnk=hpmps_buall', - megaPanelViewAll: true, - }, - ], - }, - ], - }, - { - title: 'Lorem ipsum dolor sit amet', - titleEnglish: 'Lorem ipsum dolor sit amet', - url: '', - hasMenu: true, - hasMegapanel: true, - menuSections: [ - { - heading: 'Explore', - menuItems: [ - { - title: 'Link 1', - url: '', - megapanelContent: { - headingTitle: '', - headingUrl: '', - description: '', - quickLinks: { - title: 'Title', - links: [ - { - title: 'Subnav 1', - url: '', - }, - { - title: 'Subnav 2', - url: '', - }, - { - title: 'Subnav 3', - url: '', - }, - { - title: 'Subnav 4', - url: '', - }, - ], - }, - feature: { - heading: '', - imageUrl: '', - linkTitle: '', - linkUrl: '', - }, - }, - }, - ], - }, - ], - }, - { - title: 'Consectetur adipiscing elit', - titleEnglish: 'Consectetur adipiscing elit', - url: '', - hasMenu: true, - menuSections: [ - { - heading: '', - menuItems: [ - { - title: 'Link 1', - titleEnglish: 'Link 1', - url: '', - }, - { - title: 'Menu dropdown item with extra long text', - titleEnglish: 'Menu dropdown item with extra long text', - url: '', - }, - { - title: 'Financing', - url: 'https://www.ibm.com/financing?lnk=hpmse_fin&lnk2=learn', - megapanelContent: { - headingTitle: 'Financing', - headingUrl: - 'https://www.ibm.com/financing?lnk=hpmse_fin&lnk2=learn', - description: 'Funding options that fit your business', - quickLinks: { - title: 'Quicklinks', - links: [ - { - title: 'Subnav 1', - url: '', - }, - { - title: 'Subnav 2', - url: '', - }, - { - title: 'Subnav 3', - url: '', - }, - { - title: 'Subnav 4', - url: '', - }, - ], - }, - feature: { - heading: - 'Cloud financing strategies that work for your business', - imageUrl: - 'https://www.ibm.com/images/portal/F774737R30303N19/Skyline-Card-cloud-feature380x160.jpg?1=1', - linkTitle: - 'Committed to cloud? Make the most of your cash flow.', - linkUrl: - 'https://www.ibm.com/financing/solutions/cloud-financing?lnk=hpmse_fin&lnk2=learn', - }, - }, - }, - ], - }, - ], - }, - { - title: 'Nulla quis sem at nibh elementum imperdiet', - titleEnglish: 'Nulla quis sem at nibh elementum imperdiet', - url: 'https://www.ibm.com/industries?lnk=min', - hasMenu: false, - hasMegapanel: false, - menuSections: [], - }, - { - title: 'Fusce nec tellus sed augue semper porta', - titleEnglish: 'Fusce nec tellus sed augue semper porta', - url: '', - hasMenu: true, - hasMegapanel: true, - menuSections: [ - { - heading: '', - menuItems: [ - { - title: 'IBM Developer', - url: 'https://developer.ibm.com/?lnk=hpmdev_dw&lnk2=learn', - megapanelContent: { - headingTitle: 'IBM Developer', - headingUrl: 'https://developer.ibm.com/?lnk=hpmdev_dw&lnk2=learn', - description: '', - quickLinks: { - title: 'Quicklinks', - links: [ - { - title: 'Subnav 1', - url: '', - }, - { - title: 'Subnav 2', - url: '', - }, - { - title: 'Subnav 3', - url: '', - }, - { - title: 'Subnav 4', - url: '', - }, - ], - }, - feature: { - heading: 'IBM Developer newsletters', - imageUrl: - 'https://1.dam.s81c.com/m/5908c17b26b9dd19/original/news-ibmdevnewsletters-600x245.jpg', - linkTitle: - 'Technical info on popular software development topics, including AI, Blockchain, Java and more', - linkUrl: - 'https://developer.ibm.com/newsletters/?lnk=hpmdev_dw&lnk2=learn', - }, - }, - }, - { - title: 'Blockchain', - url: 'https://developer.ibm.com/technologies/blockchain/?lnk=hpmdev_dw&lnk2=learn', - megapanelContent: { - headingTitle: 'Blockchain', - headingUrl: - 'https://developer.ibm.com/technologies/blockchain/?lnk=hpmdev_dw&lnk2=learn', - description: '', - quickLinks: { - title: 'Quicklinks', - links: [ - { - title: 'Subnav 1', - url: '', - }, - { - title: 'Subnav 2', - url: '', - }, - { - title: 'Subnav 3', - url: '', - }, - { - title: 'Subnav 4', - url: '', - }, - ], - }, - feature: { - heading: 'Blockchain 101', - imageUrl: - 'https://www.ibm.com/images/portal/E174255N41814O86/Blockchain2_600x245.jpg?1=3', - linkTitle: - 'Build a kick-starter blockchain network and start coding with the IBM Blockchain Platform Starter Plan', - linkUrl: - 'https://developer.ibm.com/tutorials/cl-ibm-blockchain-101-quick-start-guide-for-developers-bluemix-trs/?lnk=hpmdev_dw&lnk2=learn', - }, - }, - }, - { - title: 'Containers', - url: 'https://developer.ibm.com/technologies/containers/?lnk=hpmdev_dw&lnk2=learn', - megapanelContent: { - headingTitle: 'Containers', - headingUrl: - 'https://developer.ibm.com/technologies/containers/?lnk=hpmdev_dw&lnk2=learn', - description: '', - quickLinks: { - title: 'Quicklinks', - links: [ - { - title: 'Code patterns', - url: 'https://developer.ibm.com/patterns/category/containers/?lnk=hpmdev_dw&lnk2=learn', - }, - { - title: 'Tutorials', - url: 'https://developer.ibm.com/tutorials/category/containers/?lnk=hpmdev_dw&lnk2=learn', - }, - { - title: 'Events', - url: 'https://developer.ibm.com/events/category/containers/?lnk=hpmdev_dw&lnk2=learn', - }, - ], - }, - feature: { - heading: 'Make sense of Kubernetes', - imageUrl: - 'https://www.ibm.com/images/portal/E693054G76296P64/Kubernetes-Pythomn_600x245.jpg?1=2', - linkTitle: 'Deploy a simple Python application with Kubernetes', - linkUrl: - 'https://developer.ibm.com/tutorials/scalable-python-app-with-kubernetes/?lnk=hpmdev_dw&lnk2=learn', - }, - }, - }, - { - title: 'Analytics', - url: 'https://developer.ibm.com/technologies/analytics/?lnk=hpmdev_dw&lnk2=learn', - megapanelContent: { - headingTitle: 'Analytics', - headingUrl: - 'https://developer.ibm.com/technologies/analytics/?lnk=hpmdev_dw&lnk2=learn', - description: '', - quickLinks: { - title: 'Quicklinks', - links: [ - { - title: 'Code patterns', - url: 'https://developer.ibm.com/patterns/category/analytics/?lnk=hpmdev_dw&lnk2=learn', - }, - { - title: 'Tutorials', - url: 'https://developer.ibm.com/tutorials/category/analytics/?lnk=hpmdev_dw&lnk2=learn', - }, - { - title: 'Events', - url: 'https://developer.ibm.com/events/category/analytics/?lnk=hpmdev_dw&lnk2=learn', - }, - { - title: 'Developer community', - url: 'https://developer.ibm.com/watson/?lnk=hpmdev_dw&lnk2=learn', - }, - ], - }, - feature: { - heading: 'Train your data no matter where it lives', - imageUrl: - 'https://1.dam.s81c.com/m/76c0ed6f3e6386c1/original/Train-data_600x245.jpg', - linkTitle: - 'Easily and securely connect to your data source for initial model training and continuous learning', - linkUrl: - 'https://developer.ibm.com/announcements/training-machine-learning-models-in-watson-studio?lnk=hpmdev_dw&lnk2=learn', - }, - }, - }, - ], - }, - ], - }, - { - title: 'Sed cursus ante dapibus diam', - titleEnglish: 'Sed cursus ante dapibus diam', - url: 'https://www.ibm.com/support/home/?lnk=msu_usen', - hasMenu: false, - hasMegapanel: false, - menuSections: [], - }, -]; - /* eslint-enable max-len */ -export { - mastheadLinks, - customLinks, - logoData, - mastheadL1Data, - mastheadLinksV2, -}; -export default mastheadLinks; +export { mastheadLogoData, mastheadL1Data, mastheadL0Data }; diff --git a/packages/web-components/src/components/masthead/__stories__/masthead.stories.react.tsx b/packages/web-components/src/components/masthead/__stories__/masthead.stories.react.tsx index 90f647f3500..13d70278428 100644 --- a/packages/web-components/src/components/masthead/__stories__/masthead.stories.react.tsx +++ b/packages/web-components/src/components/masthead/__stories__/masthead.stories.react.tsx @@ -1,19 +1,19 @@ /** * @license * - * Copyright IBM Corp. 2020, 2023 + * Copyright IBM Corp. 2020, 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. */ -import { select } from '@storybook/addon-knobs'; +import { boolean, select } from '@storybook/addon-knobs'; import React from 'react'; // Below path will be there when an application installs `@carbon/ibmdotcom-web-components` package. // In our dev env, we auto-generate the file and re-map below path to to point to the generated file. // @ts-ignore import C4DMastheadContainer from '@carbon/ibmdotcom-web-components/es/components-react/masthead/masthead-container'; -import { mastheadL1Data, logoData } from './links'; +import { mastheadL0Data, mastheadL1Data, mastheadLogoData } from './links'; import { C4D_CUSTOM_PROFILE_LOGIN } from '../../../globals/internal/feature-flags'; import { UNAUTHENTICATED_STATUS } from '../../../internal/vendor/@carbon/ibmdotcom-services-store/types/profileAPI'; @@ -54,17 +54,24 @@ const scopeParameters = [ }, ]; -async function customTypeaheadApiFunction(searchVal) { - return fetch( - `https://ibmdocs-dev.mybluemix.net/docs/api/v1/suggest?query=${searchVal}&lang=undefined&categories=&limit=6` - ) +async function customTypeaheadApiFunction(query) { + return fetch(`https://www-api.ibm.com/search/typeahead/v1?query=${query}`) .then((response) => response.json()) .then((data) => { - const searchResults = [ - data.hints, + let searchResults = [ + // Results not including "carbon" + data.response + .filter((result) => !result[0].toLowerCase().includes('carbon')) + .map((result) => result[0]), + // Optional grouped category results including "carbon" { - title: 'Product pages', - items: data.products, + title: 'Carbon', + items: data.response + .filter((result) => result[0].toLowerCase().includes('carbon')) + .map((result) => ({ + name: result[0], + href: `https://www.example.com/${encodeURIComponent(result[0])}`, + })), }, ]; return searchResults; @@ -79,22 +86,29 @@ export const Default = (args) => { selectedMenuItem, searchPlaceholder, userStatus, - navLinks, + useMock, } = args?.MastheadComposite ?? {}; if (!hasSearch) { setTimeout(() => { document - .querySelector('cds-masthead-container') + .querySelector('c4d-masthead-container') ?.removeAttribute('has-search'); }, 1000); } + if (useMock) { + setTimeout(() => { + const masthead = document.querySelector('c4d-masthead-container'); + if (masthead) { + (masthead as any).navLinks = mastheadL0Data; + } + }, 1000); + } return ( @@ -103,13 +117,13 @@ export const Default = (args) => { export const WithCustomTypeahead = () => { document.documentElement.addEventListener( - 'cds-search-with-typeahead-input', + 'c4d-search-with-typeahead-input', async (e) => { const results = await customTypeaheadApiFunction( (e as CustomEvent).detail.value ); document.dispatchEvent( - new CustomEvent('cds-custom-typeahead-api-results', { detail: results }) + new CustomEvent('c4d-custom-typeahead-api-results', { detail: results }) ); } ); @@ -155,11 +169,16 @@ searchOpenOnload.story = { export const withPlatform = (args) => { const { platform, platformUrl } = args?.WithPlatform ?? {}; - return ( - - ); + if (platformUrl) { + setTimeout(() => { + const masthead = document.querySelector('c4d-masthead-container'); + if (masthead) { + (masthead as any).platformUrl = platformUrl; + } + }, 1000); + } + + return ; }; withPlatform.story = { @@ -180,10 +199,17 @@ withPlatform.story = { export const withL1 = (args) => { const { selectedMenuItem } = args?.MastheadComposite ?? {}; + + setTimeout(() => { + const masthead = document.querySelector('c4d-masthead-container'); + if (masthead) { + (masthead as any).l1Data = mastheadL1Data; + } + }, 1000); + return ( + selected-menu-item={selectedMenuItem}> ); }; @@ -204,12 +230,16 @@ withL1.story = { export const withAlternateLogoAndTooltip = (args) => { const { mastheadLogo } = args?.MastheadComposite ?? {}; - return ( - - ); + if (mastheadLogo === 'alternateWithTooltip') { + setTimeout(() => { + const masthead = document.querySelector('c4d-masthead-container'); + if (masthead) { + (masthead as any).logoData = mastheadLogoData; + } + }, 1000); + } + + return ; }; withAlternateLogoAndTooltip.story = { @@ -231,10 +261,14 @@ withAlternateLogoAndTooltip.story = { }; export const WithScopedSearch = () => { - return ( - - ); + setTimeout(() => { + const masthead = document.querySelector('c4d-masthead-container'); + if (masthead) { + (masthead as any).scopeParameters = scopeParameters; + } + }, 1000); + + return ; }; WithScopedSearch.story = { @@ -287,6 +321,7 @@ export default { 'custom profile login url (customProfileLogin)', 'https://www.example.com/' ), + useMock: boolean('use mock nav data', false), }), }, }, diff --git a/packages/web-components/src/components/masthead/__stories__/masthead.stories.ts b/packages/web-components/src/components/masthead/__stories__/masthead.stories.ts index f1bd3502861..40589463e7b 100644 --- a/packages/web-components/src/components/masthead/__stories__/masthead.stories.ts +++ b/packages/web-components/src/components/masthead/__stories__/masthead.stories.ts @@ -1,7 +1,7 @@ /** * @license * - * Copyright IBM Corp. 2020, 2023 + * Copyright IBM Corp. 2020, 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. @@ -16,7 +16,7 @@ import c4dLeftNav from '../left-nav'; import '../masthead-container'; import styles from './masthead.stories.scss'; import { ifDefined } from 'lit/directives/if-defined.js'; -import { mastheadLinksV2 as links, mastheadL1Data, logoData } from './links'; +import { mastheadL0Data, mastheadL1Data, mastheadLogoData } from './links'; import { UNAUTHENTICATED_STATUS, MASTHEAD_AUTH_METHOD, @@ -110,7 +110,7 @@ export const Default = (args) => { has-profile="${hasProfile}" has-search="${hasSearch}" has-contact="${hasContact}" - .navLinks="${links}" + .l0Data="${mastheadL0Data}" .authenticatedProfileItems="${ifDefined(authenticatedProfileItems)}" .unauthenticatedProfileItems="${ifNonEmpty( unauthenticatedProfileItems @@ -133,51 +133,6 @@ export const Default = (args) => { `; }; -export const withCloudData = (args) => { - const { - customProfileLogin, - hasSearch, - selectedMenuItem, - searchPlaceholder, - useMock, - } = args?.MastheadComposite ?? {}; - - return html` - - ${useMock - ? html` - - ` - : html` - - `} - `; -}; - export const WithCustomTypeahead = (args) => { const { useMock } = args?.MastheadComposite ?? {}; @@ -200,7 +155,7 @@ export const WithCustomTypeahead = (args) => { ${useMock ? html` { ${useMock ? html` { ? html` { ${useMock ? html` { ${useMock ? html` { unauthenticatedProfileItems )}" .logoData="${mastheadLogo === 'alternateWithTooltip' - ? logoData + ? mastheadLogoData : null}"> ` : html` `} `; @@ -474,7 +429,7 @@ export const WithScopedSearch = (args) => { ${useMock ? html` { const { customProfileLogin, @@ -66,7 +69,6 @@ export const Default = (args) => { searchPlaceholder, hasProfile, hasSearch, - navLinks, } = args?.MastheadComposite ?? {}; const { useMock } = args?.Other ?? {}; @@ -85,7 +87,7 @@ export const Default = (args) => { .authenticatedProfileItems="${ifDefined(authenticatedProfileItems)}" ?has-profile="${hasProfile}" ?has-search="${hasSearch}" - .navLinks="${navLinks}" + .l0Data="${mastheadL0Data}" .unauthenticatedProfileItems="${ifDefined( unauthenticatedProfileItems )}" @@ -99,7 +101,7 @@ export const Default = (args) => { selected-menu-item="${ifDefined(selectedMenuItem)}" user-status="${ifDefined(userStatus)}" searchPlaceholder="${ifDefined(searchPlaceholder)}" - .navLinks="${navLinks}" + data-endpoint=${dataEndpoint} ?has-profile="${hasProfile}" ?has-search="${hasSearch}" custom-profile-login="${customProfileLogin}" @@ -163,9 +165,6 @@ export default { const useMock = inPercy() || new URLSearchParams(window.location.search).has('mock'); return { - MastheadComposite: { - navLinks: !useMock ? undefined : links, - }, Other: { useMock, }, @@ -181,7 +180,6 @@ export default { selectedMenuItem: 'Services & Consulting', userStatus: userStatuses.unauthenticated, customProfileLogin: 'https://www.example.com/', - navLinks: links, }, }, }, diff --git a/packages/web-components/src/components/masthead/__tests__/cloud-masthead-composite.test.ts b/packages/web-components/src/components/masthead/__tests__/cloud-masthead-composite.test.ts deleted file mode 100644 index 4484b8b5a4c..00000000000 --- a/packages/web-components/src/components/masthead/__tests__/cloud-masthead-composite.test.ts +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2021, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import { html, render } from 'lit/html.js'; - -describe('c4d-cloud-masthead-composite', function () { - describe('Rendering Cloud-specific global bar', function () { - it('should not render cloud profile when unauthenticated', async function () { - render( - html` - - `, - document.body - ); - await Promise.resolve(); - const cloudMastheadComposite = document.body.querySelector( - 'c4d-cloud-masthead-composite' - ); - expect( - cloudMastheadComposite?.shadowRoot?.querySelector( - 'c4d-cloud-masthead-profile' - ) - ).toBeNull(); - }); - - it('should render cloud profile when authenticated', async function () { - render( - html` - - `, - document.body - ); - await Promise.resolve(); - const cloudMastheadComposite = document.body.querySelector( - 'c4d-cloud-masthead-composite' - ); - expect( - cloudMastheadComposite?.shadowRoot?.querySelector( - 'c4d-cloud-masthead-profile' - ) - ).not.toBeNull(); - }); - }); -}); diff --git a/packages/web-components/src/components/masthead/__tests__/masthead-composite.test.ts b/packages/web-components/src/components/masthead/__tests__/masthead-composite.test.ts index 5e260271550..57e73da330f 100644 --- a/packages/web-components/src/components/masthead/__tests__/masthead-composite.test.ts +++ b/packages/web-components/src/components/masthead/__tests__/masthead-composite.test.ts @@ -1,7 +1,7 @@ /** * @license * - * Copyright IBM Corp. 2020, 2023 + * Copyright IBM Corp. 2020, 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. @@ -23,13 +23,13 @@ const template = (props?) => { language="${ifDefined(language)}" user-status="${ifDefined(userStatus)}" .authenticatedProfileItems="${ifDefined(authenticatedProfileItems)}" - .navLinks="${navLinks}" + .l0Data="${navLinks}" .unauthenticatedProfileItems="${ifDefined(unauthenticatedProfileItems)}"> `; }; -describe('cds-masthead-composite', function () { +describe('c4d-masthead-composite', function () { const events = new EventManager(); describe('Rendering global bar', function () { @@ -63,7 +63,7 @@ describe('cds-masthead-composite', function () { const mastheadComposite = document.body.querySelector( 'c4d-masthead-composite' ); - expect(mastheadComposite!.querySelector('cds-top-nav')).toBeNull(); + expect(mastheadComposite!.querySelector('c4d-top-nav')).toBeNull(); }); }); diff --git a/packages/web-components/src/components/masthead/__tests__/masthead.steps.js b/packages/web-components/src/components/masthead/__tests__/masthead.steps.js index a6427b810eb..03f718ab66f 100644 --- a/packages/web-components/src/components/masthead/__tests__/masthead.steps.js +++ b/packages/web-components/src/components/masthead/__tests__/masthead.steps.js @@ -1,13 +1,13 @@ /** * @license * - * Copyright IBM Corp. 2020, 2023 + * Copyright IBM Corp. 2020, 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. */ -describe('cds-masthead-*', () => { +describe('c4d-masthead-*', () => { describe('With wide screen', () => { beforeEach(async () => { await page.setViewportSize({ width: 1280, height: 720 }); @@ -18,7 +18,7 @@ describe('cds-masthead-*', () => { it('should support clicking the logo', async () => { const promiseNavigation = page.waitForNavigation(); - await page.click('cds-masthead-logo'); + await page.click('c4d-masthead-logo'); await promiseNavigation; expect(await page.evaluate(() => window.location.href)).toMatch( 'https://www.ibm.com' @@ -26,9 +26,9 @@ describe('cds-masthead-*', () => { }); it('should support navigating in profile menu', async () => { - await page.click('cds-masthead-profile'); + await page.click('c4d-masthead-profile'); const promiseNavigation = page.waitForNavigation(); - await page.click('cds-masthead-profile-item[href*="authorize"]'); + await page.click('c4d-masthead-profile-item[href*="authorize"]'); await promiseNavigation; expect(await page.evaluate(() => window.location.href)).toMatch( 'https://idaas.iam.ibm.com' @@ -36,9 +36,9 @@ describe('cds-masthead-*', () => { }); it('should support navigating in top nav menu', async () => { - await page.click('cds-megamenu-top-nav-menu:first-of-type'); + await page.click('c4d-megamenu-top-nav-menu:first-of-type'); const promiseNavigation = page.waitForNavigation(); - await page.click('cds-megamenu-link-with-icon:first-of-type'); + await page.click('c4d-megamenu-link-with-icon:first-of-type'); await promiseNavigation; expect(await page.evaluate(() => window.location.href)).toMatch( 'https://www.ibm.com' @@ -46,14 +46,14 @@ describe('cds-masthead-*', () => { }); it('should support showing/hiding the search box', async () => { - await page.click('cds-masthead-search button[part="open-button"]'); + await page.click('c4d-masthead-search button[part="open-button"]'); await expect(page).toHaveSelector( - 'cds-masthead-search input[part="search-input"]', + 'c4d-masthead-search input[part="search-input"]', { state: 'visible' } ); - await page.click('cds-masthead-search button[part="close-button"]'); + await page.click('c4d-masthead-search button[part="close-button"]'); await expect(page).toHaveSelector( - 'cds-masthead-search input[part="search-input"]', + 'c4d-masthead-search input[part="search-input"]', { state: 'hidden' } ); }); @@ -68,10 +68,10 @@ describe('cds-masthead-*', () => { }); it('should support navigating in left nav menu', async () => { - await page.click('cds-masthead-menu-button'); - await page.click('cds-left-nav-menu[title*="Products"]'); - await page.click('cds-left-nav-menu[title="Industries"]'); - await page.click('cds-left-nav-menu-item[title="Healthcare"]'); + await page.click('c4d-masthead-menu-button'); + await page.click('c4d-left-nav-menu[title*="Products"]'); + await page.click('c4d-left-nav-menu[title="Industries"]'); + await page.click('c4d-left-nav-menu-item[title="Healthcare"]'); expect(await page.evaluate(() => window.location.href)).toMatch( 'https://www.ibm.com/industries/healthcare' ); diff --git a/packages/web-components/src/components/masthead/cloud/cloud-button-cta.ts b/packages/web-components/src/components/masthead/cloud/cloud-button-cta.ts deleted file mode 100644 index de40ec7f238..00000000000 --- a/packages/web-components/src/components/masthead/cloud/cloud-button-cta.ts +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2021, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import settings from '../../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import { CTA_TYPE } from '../../cta/defs'; -import C4DButtonExpressive from '../../button/button'; -import styles from './cloud-masthead.scss'; -import { carbonElement as customElement } from '../../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element'; - -export { CTA_TYPE }; - -const { stablePrefix: c4dPrefix } = settings; - -/** - * Cloud Button CTA. - * - * @element c4d-cloud-button-cta - */ -@customElement(`${c4dPrefix}-cloud-button-cta`) -class C4DCloudButtonCTA extends C4DButtonExpressive { - static styles = styles; -} - -export default C4DCloudButtonCTA; diff --git a/packages/web-components/src/components/masthead/cloud/cloud-left-nav-item.ts b/packages/web-components/src/components/masthead/cloud/cloud-left-nav-item.ts deleted file mode 100644 index b4405f36553..00000000000 --- a/packages/web-components/src/components/masthead/cloud/cloud-left-nav-item.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2020, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import CDSSideNavLink from '../../../internal/vendor/@carbon/web-components/components/ui-shell/side-nav-link.js'; -import settings from '../../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import styles from './cloud-masthead.scss'; -import { carbonElement as customElement } from '../../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element.js'; - -const { stablePrefix: c4dPrefix } = settings; - -/** - * Cloud-specific masthead left nav item. - * - * @element c4d-cloud-left-nav-item - */ -@customElement(`${c4dPrefix}-cloud-left-nav-item`) -class C4DCloudLeftNavItem extends CDSSideNavLink { - static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader -} - -export default C4DCloudLeftNavItem; diff --git a/packages/web-components/src/components/masthead/cloud/cloud-masthead-composite.ts b/packages/web-components/src/components/masthead/cloud/cloud-masthead-composite.ts deleted file mode 100644 index 91bdc27d1de..00000000000 --- a/packages/web-components/src/components/masthead/cloud/cloud-masthead-composite.ts +++ /dev/null @@ -1,499 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2021, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import { html } from 'lit'; -import { property } from 'lit/decorators.js'; -import { ifDefined } from 'lit/directives/if-defined.js'; -import settings from '../../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import { globalInit } from '../../../internal/vendor/@carbon/ibmdotcom-services/services/global/global'; -import './cloud-button-cta'; -import './cloud-left-nav-item'; -import './cloud-masthead-global-bar'; -import './cloud-masthead-profile'; -import './cloud-top-nav-name'; -import './cloud-megamenu'; -import './cloud-megamenu-tabs'; -import './cloud-megamenu-tab'; -import './cloud-megamenu-left-navigation'; -import './cloud-megamenu-right-navigation'; -import './cloud-megamenu-category-heading'; -import './cloud-megamenu-category-link'; -import './cloud-megamenu-category-link-group'; -import { - MastheadMenuItem, - MastheadProfileItem, -} from '../../../internal/vendor/@carbon/ibmdotcom-services-store/types/translateAPI.d'; -import { UNAUTHENTICATED_STATUS } from '../../../internal/vendor/@carbon/ibmdotcom-services-store/types/cloudAccountAuthAPI'; -import { MASTHEAD_AUTH_METHOD } from '../../../internal/vendor/@carbon/ibmdotcom-services-store/types/profileAPI'; -import styles from './cloud-masthead.scss'; -import C4DMastheadComposite, { - NAV_ITEMS_RENDER_TARGET, -} from '../masthead-composite'; -import { carbonElement as customElement } from '../../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element.js'; - -const { stablePrefix: c4dPrefix } = settings; - -// Magic Number: 960px matches masthead.scss's `$breakpoint--desktop-nav`. -const layoutBreakpoint = window.matchMedia(`(max-width: 959px)`); - -/** - * Component that renders masthead from links, etc. data. - * - * @element c4d-cloud-masthead-composite - */ - -@customElement(`${c4dPrefix}-cloud-masthead-composite`) -class C4DCloudMastheadComposite extends C4DMastheadComposite { - /** - * The placeholder for `loadUserStatus()` Redux action that will be mixed in. - * - * @internal - */ - _loadUserStatus?: (authMethod?: string) => void; - - /** - * The profile items for unauthenticated state. - */ - @property({ attribute: false }) - authenticatedCtaButtons?: MastheadProfileItem[]; - - /** - * Text for Contact us button - */ - @property({ attribute: false }) - contactUsButton?: MastheadProfileItem; - - /** - * `true` if Contact us should be shown. - */ - @property({ type: String, reflect: true, attribute: 'has-contact' }) - hasContact = 'true'; - - /** - * The profile items for unauthenticated state. - */ - @property({ attribute: false }) - unauthenticatedCtaButtons?: MastheadProfileItem[]; - - /** - * The selected authentication method, either 'cookie' or 'api'. - */ - @property({ attribute: 'auth-method' }) - authMethod = MASTHEAD_AUTH_METHOD.COOKIE; - - /** - * The user authentication status. - */ - @property({ attribute: 'user-status' }) - userStatus = UNAUTHENTICATED_STATUS; - - /** - * The path to which a user will be redirected after successful login. - */ - @property({ type: String, reflect: false, attribute: 'redirect-path' }) - redirectPath? = ''; - - /** - * Whether the nav should load as `left-nav` or `top-nav` - */ - _isMobileVersion = layoutBreakpoint.matches; - - /** - * Render MegaMenu content - * - * @param sections menu section data object - * @param parentKey parent key - */ - // eslint-disable-next-line class-methods-use-this - protected _renderMegaMenu(sections, parentKey) { - let viewAllLink; - type menuItem = MastheadMenuItem & { itemKey: String }; - const sortedMenuItems: menuItem[] = []; - sections[0].menuItems?.forEach((item, i) => { - if (item.megaPanelViewAll) { - viewAllLink = item; - return viewAllLink; - } - - return sortedMenuItems.push({ ...item, itemKey: `${parentKey}-${i}` }); - }); - - return html` - - - - ${sortedMenuItems.map((item) => { - return html` - ${item.title} - `; - })} - - - - ${sortedMenuItems.map((item) => { - return html` - - `; - })} - - - `; - } - - /** - * Renders the left nav menus sections - * - * @param object heading heading of menu section - * @param object.menuItems menu items - * @param object.heading heading heading of menu section - * @param object.isSubmenu determines whether menu section is a submenu section - * @param object.showBackButton Determines whether to show back button - * @param object.sectionTitle title of menu section - * @param object.sectionUrl section title url of menu section - * @param object.sectionId id of menu section - */ - protected _renderLeftNavMenuSections({ - menuItems, - heading = '', - isSubmenu = false, - showBackButton = false, - sectionTitle = '', - sectionUrl = '', - sectionId = '', - }) { - const { - userStatus, - authenticatedProfileItems, - unauthenticatedProfileItems, - authenticatedCtaButtons, - unauthenticatedCtaButtons, - } = this; - const authenticated = userStatus !== 'anonymous'; - const profileItems = authenticated - ? authenticatedProfileItems - : unauthenticatedProfileItems; - const ctaButtons = authenticated - ? authenticatedCtaButtons - : unauthenticatedCtaButtons; - - const items = menuItems.map((elem) => { - if (elem.menu) { - return html` - - - `; - } - - return html` - - `; - }); - - if (heading) { - items.unshift( - html` - ${heading} - ` - ); - } - - if (!isSubmenu) { - items.push( - html` - ${authenticated - ? null - : html` - ${profileItems?.map((item) => { - return html` - - `; - })} - `} - ${ctaButtons?.map((item) => { - return html` - - `; - })} - ` - ); - } - - return html` - - ${items} - - `; - } - - firstUpdated() { - const { language, dataEndpoint } = this; - globalInit(); - if (language) { - this._setLanguage?.(language); - } - this._loadTranslation?.(language, dataEndpoint).catch(() => {}); // The error is logged in the Redux store - this._loadUserStatus?.(this.authMethod); - - this.style.zIndex = '900'; - - // Allows conditional rendering of left/top navs. - layoutBreakpoint.addEventListener('change', () => { - this._isMobileVersion = layoutBreakpoint.matches; - this.requestUpdate(); - }); - } - - render() { - const { - _isMobileVersion: isMobileVersion, - activateSearch, - authenticatedProfileItems, - authenticatedCtaButtons, - contactUsButton, - hasContact, - platform, - platformUrl, - inputTimeout, - mastheadAssistiveText, - menuBarAssistiveText, - menuButtonAssistiveTextActive, - menuButtonAssistiveTextInactive, - language, - openSearchDropdown, - searchPlaceholder, - unauthenticatedProfileItems, - unauthenticatedCtaButtons, - userStatus, - l1Data, - } = this; - const authenticated = userStatus !== 'anonymous'; - const profileItems = authenticated - ? authenticatedProfileItems - : unauthenticatedProfileItems; - const ctaButtons = authenticated - ? authenticatedCtaButtons - : unauthenticatedCtaButtons; - const formattedLang = language - ?.toLowerCase() - .replace(/-(.*)/, (m) => m.toUpperCase()); - let platformAltUrl = platformUrl; - if (platformUrl && formattedLang) { - if ( - typeof platformUrl === 'object' && - Object.prototype.hasOwnProperty.call(platformUrl, formattedLang) - ) { - platformAltUrl = platformUrl[formattedLang].url || platformUrl; - } - } - - return html` - ${isMobileVersion - ? html` - - - ${!platform - ? undefined - : html` - ${platform} - `} - ${this._renderNavItems({ - target: NAV_ITEMS_RENDER_TARGET.LEFT_NAV, - hasL1: !!l1Data, - })} - - ` - : ''} - - ${isMobileVersion - ? html` - - - ` - : ''} - ${this._renderLogo()} - ${!platform - ? undefined - : html` - ${platform} - `} - ${l1Data - ? undefined - : !isMobileVersion - ? html` - - ${this._renderNavItems({ - target: NAV_ITEMS_RENDER_TARGET.TOP_NAV, - hasL1: false, - })} - - ` - : undefined} - - ${authenticated - ? html` - - - ${profileItems?.map( - ({ title, url }) => - html` - ${title} - ` - )} - - ${hasContact === 'false' - ? '' - : html` - ${contactUsButton?.title} - `} - ${ctaButtons?.map( - ({ title, url }) => - html` - ${title} - ` - )} - - ` - : html` - - ${hasContact === 'false' - ? '' - : html` - ${contactUsButton?.title} - `} - ${profileItems?.map( - ({ title, url }) => - html` - ${title} - ` - )} - ${ctaButtons?.map( - ({ title, url }) => - html` - ${title} - ` - )} - - `} - ${!l1Data ? undefined : this._renderL1()} - - - `; - } - - static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader -} - -export default C4DCloudMastheadComposite; diff --git a/packages/web-components/src/components/masthead/cloud/cloud-masthead-container.ts b/packages/web-components/src/components/masthead/cloud/cloud-masthead-container.ts deleted file mode 100644 index bdee02caac1..00000000000 --- a/packages/web-components/src/components/masthead/cloud/cloud-masthead-container.ts +++ /dev/null @@ -1,142 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2021, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ -import pickBy from 'lodash-es/pickBy.js'; -import { - ActionCreatorsMapObject, - Dispatch, - Store, - bindActionCreators, -} from 'redux'; -import settings from '../../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import { CloudAccountAuthAPIState } from '../../../internal/vendor/@carbon/ibmdotcom-services-store/types/cloudAccountAuthAPI.d'; -import store from '../../../internal/vendor/@carbon/ibmdotcom-services-store/store'; -import { LocaleAPIActions } from '../../../internal/vendor/@carbon/ibmdotcom-services-store/actions/localeAPI.d'; -import { TranslateAPIActions } from '../../../internal/vendor/@carbon/ibmdotcom-services-store/actions/translateAPI.d'; -import { loadUserStatus } from '../../../internal/vendor/@carbon/ibmdotcom-services-store/actions/cloudAccountAuthAPI'; -// eslint-disable-next-line max-len -import { CloudAccountAuthAPIActions } from '../../../internal/vendor/@carbon/ibmdotcom-services-store/actions/cloudAccountAuthAPI.d'; -import ConnectMixin from '../../../globals/mixins/connect'; -import { loadTranslation } from '../../../internal/vendor/@carbon/ibmdotcom-services-store/actions/translateAPI'; -import { - loadLanguage, - setLanguage, -} from '../../../internal/vendor/@carbon/ibmdotcom-services-store/actions/localeAPI'; -import { - MastheadContainerState, - MastheadContainerStateProps, -} from '../masthead-container'; -import C4DCloudMastheadComposite from './cloud-masthead-composite'; -import { carbonElement as customElement } from '../../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element'; - -const { stablePrefix: c4dPrefix } = settings; - -/** - * The Redux state used for `` - */ -export interface CloudMastheadContainerState - extends Omit { - /** - * The Redux state for `CloudAccountAuthAPI` - */ - cloudAccountAuthAPI?: CloudAccountAuthAPIState; -} - -/** - * The Redux actions used for `. - */ -export type CloudMastheadContainerActions = - | ReturnType - | ReturnType - | ReturnType - | ReturnType; - -/** - * @param state The Redux state for masthead. - * @returns The converted version of the given state, tailored for ``. - */ -export function mapStateToProps( - state: CloudMastheadContainerState -): MastheadContainerStateProps { - const { localeAPI, translateAPI, cloudAccountAuthAPI } = state; - const { language } = localeAPI ?? {}; - const { translations } = translateAPI ?? {}; - const { request } = cloudAccountAuthAPI ?? {}; - return pickBy( - { - authenticatedProfileItems: !language - ? undefined - : translations?.[language]?.masthead?.profileMenu.signedin.links, - authenticatedCtaButtons: !language - ? undefined - : translations?.[language]?.masthead?.profileMenu.signedin.ctaButtons, - contactUsButton: !language - ? undefined - : translations?.[language]?.masthead?.contact, - navLinks: !language - ? undefined - : translations?.[language]?.mastheadNav?.links, - unauthenticatedProfileItems: !language - ? undefined - : translations?.[language]?.masthead?.profileMenu.signedout.links, - unauthenticatedCtaButtons: !language - ? undefined - : translations?.[language]?.masthead?.profileMenu.signedout.ctaButtons, - logoData: !language - ? undefined - : translations?.[language]?.masthead?.logo, - userStatus: request?.user, - language, - }, - (value) => value !== undefined - ); -} - -/** - * @param dispatch The Redux `dispatch()` API. - * @returns The methods in `` to dispatch Redux actions. - */ -export function mapDispatchToProps( - dispatch: Dispatch< - LocaleAPIActions | TranslateAPIActions | CloudAccountAuthAPIActions - > -) { - return bindActionCreators< - CloudMastheadContainerActions, - ActionCreatorsMapObject - >( - { - _loadLanguage: loadLanguage, - _setLanguage: setLanguage, - _loadTranslation: loadTranslation, - _loadUserStatus: loadUserStatus, - }, - dispatch as Dispatch // TS definition of `bindActionCreators()` seems to have no templated `Dispatch` - ); -} -/** - * Container component for Cloud masthead. - * - * @element c4d-cloud-masthead-container - */ -@customElement(`${c4dPrefix}-cloud-masthead-container`) -class C4DCloudMastheadContainer extends ConnectMixin< - CloudMastheadContainerState, - LocaleAPIActions | TranslateAPIActions | CloudAccountAuthAPIActions, - MastheadContainerStateProps, - ActionCreatorsMapObject ->( - store as Store< - CloudMastheadContainerState, - LocaleAPIActions | TranslateAPIActions | CloudAccountAuthAPIActions - >, - mapStateToProps, - mapDispatchToProps -)(C4DCloudMastheadComposite) {} - -export default C4DCloudMastheadContainer; diff --git a/packages/web-components/src/components/masthead/cloud/cloud-masthead-global-bar.ts b/packages/web-components/src/components/masthead/cloud/cloud-masthead-global-bar.ts deleted file mode 100644 index c01503024b7..00000000000 --- a/packages/web-components/src/components/masthead/cloud/cloud-masthead-global-bar.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2021, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import settings from '../../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import styles from './cloud-masthead.scss'; -import C4DMastheadGlobalBar from '../masthead-global-bar'; -import { carbonElement as customElement } from '../../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element'; - -const { stablePrefix: c4dPrefix } = settings; - -/** - * The action bar in Cloud masthead. - * - * @element c4d-cloud-masthead-global-bar - */ -@customElement(`${c4dPrefix}-cloud-masthead-global-bar`) -class C4DCloudMastheadGlobalBar extends C4DMastheadGlobalBar { - static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader -} - -export default C4DCloudMastheadGlobalBar; diff --git a/packages/web-components/src/components/masthead/cloud/cloud-masthead-profile.ts b/packages/web-components/src/components/masthead/cloud/cloud-masthead-profile.ts deleted file mode 100644 index db14d600469..00000000000 --- a/packages/web-components/src/components/masthead/cloud/cloud-masthead-profile.ts +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2021, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import { ifDefined } from 'lit/directives/if-defined.js'; -import { html } from 'lit'; -import User20 from '../../../internal/vendor/@carbon/web-components/icons/user/20.js'; -import settings from '../../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import styles from './cloud-masthead.scss'; -import C4DMastheadProfile from '../masthead-profile'; -import { carbonElement as customElement } from '../../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element.js'; - -const { prefix, stablePrefix: c4dPrefix } = settings; - -/** - * The Cloud-specific profile menu UI in the masthead. - * - * @element c4d-cloud-masthead-profile - */ -@customElement(`${c4dPrefix}-cloud-masthead-profile`) -class C4DCloudMastheadProfile extends C4DMastheadProfile { - render() { - const { - expanded, - menuLabel, - triggerLabel, - _handleClick: handleClick, - } = this; - return html` -
- ${User20()} - -
    - -
- `; - } - - static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader -} - -export default C4DCloudMastheadProfile; diff --git a/packages/web-components/src/components/masthead/cloud/cloud-masthead.scss b/packages/web-components/src/components/masthead/cloud/cloud-masthead.scss deleted file mode 100644 index 7bda7f819ee..00000000000 --- a/packages/web-components/src/components/masthead/cloud/cloud-masthead.scss +++ /dev/null @@ -1,346 +0,0 @@ -// -// Copyright IBM Corp. 2021, 2023 -// -// This source code is licensed under the Apache-2.0 license found in the -// LICENSE file in the root directory of this source tree. -// - -@use '@carbon/styles/scss/breakpoint' as *; -@use '@carbon/styles/scss/config' as *; -@use '@carbon/styles/scss/spacing' as *; -@use '@carbon/styles/scss/theme' as *; -@use '@carbon/styles/scss/type' as *; -@use '@carbon/styles/scss/components/button/tokens' as *; -@use '@carbon/styles/scss/utilities/convert' as *; -@use '@carbon/ibmdotcom-styles/scss/components/masthead' as *; -@use '../masthead'; -@use '../../cta/cta'; -@use '@carbon/ibmdotcom-styles/scss/globals/utils/flex-grid' as *; -@use '@carbon/ibmdotcom-styles/scss/globals/vars' as *; - -// Cloud Masthead. - -:host(#{$c4d-prefix}-cloud-masthead-container), -#{$c4d-prefix}-cloud-masthead-container { - position: relative; -} - -:host(#{$c4d-prefix}-cloud-masthead-global-bar) { - @extend :host(#{$c4d-prefix}-masthead-global-bar); - - z-index: 0; - flex: none; - - background-color: $background; -} - -:host(#{$c4d-prefix}-cloud-masthead-global-bar) - ::slotted(#{$c4d-prefix}-cloud-button-cta) { - @include breakpoint-down(md) { - display: none; - } -} - -:host(#{$c4d-prefix}-cloud-button-cta) { - @extend :host(#{$c4d-prefix}-button-cta); - - margin: 0; - - padding-inline-end: 0; - - &.console .#{$prefix}--btn--ghost { - border-inline-start: 1px solid $button-separator; - color: $link-secondary; - } - - .#{$prefix}--btn { - padding: calc(0.875rem - 3px) to-rem(15px); - } - - .#{$prefix}--btn--ghost { - color: $text-secondary; - - &:hover, - &:focus { - color: $text-primary; - } - } -} - -:host(#{$c4d-prefix}-cloud-top-nav-name) { - position: relative; - z-index: 1; - background-color: $background; - outline: none; - - a.#{$prefix}--header__name { - margin-inline-start: 0; - - @include masthead-top-nav-name; - - @include breakpoint-down(800px) { - position: absolute; - display: flex; - inset-block-start: 0; - inset-inline-start: 0; - } - - @include breakpoint(lg) { - margin-inline-start: 0; - } - - @include breakpoint(xlg) { - position: relative; - margin-inline-start: $spacing-05; - } - } -} - -// Cloud Megamenu. - -:host(#{$c4d-prefix}-cloud-megamenu), -.#{$prefix}--masthead__megamenu { - position: relative; - - &::after { - position: fixed; - background: linear-gradient( - rgba(255, 255, 255, 0.001), - $background - ); /* transparent keyword is broken in Safari */ - - block-size: $spacing-09; - - content: ''; - inline-size: 100%; - inset-block-end: 0; - } - - .#{$prefix}--masthead__megamenu__container { - block-size: 100%; - inline-size: 100%; - overflow-x: hidden; - } - - .#{$prefix}--masthead__megamenu__container--row { - // Override flex-direction: column set in _masthead-megamenu.scss. - @include breakpoint-between(960px, 1055px) { - flex-direction: inherit; - } - } -} - -:host(#{$c4d-prefix}-cloud-megamenu-left-navigation) { - @include make-col(4, 16); - - display: flex; - flex-direction: column; - justify-content: space-between; - border-inline-end: to-rem(1px) solid $border-subtle-01; - - @include breakpoint(md) { - min-block-size: to-rem(580px); - } - - @include breakpoint(xlg) { - min-block-size: to-rem(475px); - } -} - -:host(#{$c4d-prefix}-cloud-megamenu-right-navigation) { - @include make-col(12, 16); - - display: flex; - flex-direction: column; - margin-block-end: $spacing-07; - padding-block-start: $spacing-06; -} - -:host(#{$c4d-prefix}-cloud-megamenu-tabs) { - display: flex; - flex-direction: column; - margin-block: to-rem(18px); - - .#{$prefix}--tabs-trigger { - display: none; - } -} - -:host(#{$c4d-prefix}-cloud-megamenu-tab) { - outline: 0; - - button { - @include type-style(body-short-01); - - padding: to-rem(6px) $spacing-05; - border: none; - background-color: $background; - - color: $text-secondary; - cursor: pointer; - - inline-size: 100%; - text-align: start; - - &:hover, - &:focus { - color: $text-primary; - } - - &:hover { - background-color: $background-hover; - } - - &:focus { - outline: $spacing-01 solid $focus; - outline-offset: -#{$spacing-01}; - } - } -} - -:host(#{$c4d-prefix}-cloud-megamenu-tab)[selected] button { - background-color: $background-selected; - color: $text-primary; -} - -:host(#{$c4d-prefix}-cloud-megamenu-category-link-group) { - display: flex; - flex-flow: wrap; - justify-content: flex-start; -} - -:host(#{$c4d-prefix}-cloud-megamenu-category-link) { - inline-size: 100%; - max-inline-size: 50%; - outline: 0; - - @include breakpoint(xlg) { - max-inline-size: 33.33%; - } - - a { - display: block; - padding: $spacing-04 $spacing-05; - block-size: 100%; - - p { - @include type-style('heading-01'); - - color: $text-primary; - } - - span { - @include type-style(body-short-01); - - display: block; - - color: $text-secondary; - inline-size: 90%; - } - - &:hover { - background-color: $background-hover; - text-decoration: none; - - span { - color: $text-primary; - } - } - - &:focus { - outline: $spacing-01 solid $focus; - outline-offset: #{$spacing-01}; - } - } -} - -:host(#{$c4d-prefix}-cloud-megamenu-category-heading) { - display: block; - padding: 0 $spacing-05; - inline-size: 66.66%; - margin-block-end: $spacing-07; - - @include breakpoint(lg) { - inline-size: auto; - } - - h2 { - display: flex; - margin-block-end: $spacing-03; - - a { - align-self: center; - color: $text-primary; - text-decoration: none; - - svg { - margin: 0 $spacing-03; - fill: $icon-primary; - padding-block-start: $spacing-02; - - /* stylelint-disable-next-line comment-whitespace-inside */ - /* !rtl:raw: - transform: scaleX(-1); - */ - } - - &:hover { - text-decoration: underline; - } - - &:focus { - outline: $spacing-01 solid $focus; - outline-offset: -#{$spacing-01}; - } - } - } - - span { - display: block; - @include type-style(body-short-01); - - color: $text-secondary; - - @include breakpoint(lg) { - inline-size: 40%; - } - } -} - -:host(#{$c4d-prefix}-cloud-left-nav-item) { - @extend :host(#{$c4d-prefix}-left-nav-item); - - a.#{$prefix}--side-nav__link .#{$prefix}--side-nav__link-text { - color: $text-secondary; - - &:hover, - &:focus { - color: $text-primary; - } - } - - &:last-child { - a.#{$prefix}--side-nav__link .#{$prefix}--side-nav__link-text { - color: $link-primary; - - &:hover, - &:focus { - color: $link-secondary; - } - } - } -} - -:host(#{$c4d-prefix}-cloud-masthead-profile) - .#{$prefix}--header__menu-title[aria-expanded='true'] - + .#{$prefix}--header__menu { - @include breakpoint-down(md) { - inline-size: 100vw; - } -} - -:host(#{$c4d-prefix}-cloud-masthead-profile) a.#{$prefix}--header__menu-item { - svg { - fill: $icon-secondary; - } -} diff --git a/packages/web-components/src/components/masthead/cloud/cloud-megamenu-category-heading.ts b/packages/web-components/src/components/masthead/cloud/cloud-megamenu-category-heading.ts deleted file mode 100644 index 6f76ded7831..00000000000 --- a/packages/web-components/src/components/masthead/cloud/cloud-megamenu-category-heading.ts +++ /dev/null @@ -1,48 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2020, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import { LitElement, html } from 'lit'; -import { property } from 'lit/decorators.js'; -import ArrowRight32 from '../../../internal/vendor/@carbon/web-components/icons/arrow--right/32.js'; -import settings from '../../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import styles from './cloud-masthead.scss'; -import { carbonElement as customElement } from '../../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element.js'; - -const { stablePrefix: c4dPrefix } = settings; - -/** - * Cloud MegaMenu Category Heading. - * - * @element c4d-cloud-megamenu-category-heading - */ -@customElement(`${c4dPrefix}-cloud-megamenu-category-heading`) -class C4DCloudMegaMenuCategoryHeading extends LitElement { - /** - * href. - */ - @property({ reflect: true }) - href = ''; - - /** - * Megamenu content category heading - */ - @property({ reflect: true }) - title = ''; - - render() { - return html` -

${this.title} ${ArrowRight32()}

- - `; - } - - static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader -} - -export default C4DCloudMegaMenuCategoryHeading; diff --git a/packages/web-components/src/components/masthead/cloud/cloud-megamenu-category-link-group.ts b/packages/web-components/src/components/masthead/cloud/cloud-megamenu-category-link-group.ts deleted file mode 100644 index 699fe4b4a22..00000000000 --- a/packages/web-components/src/components/masthead/cloud/cloud-megamenu-category-link-group.ts +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2020, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import { LitElement, html } from 'lit'; -import settings from '../../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import { carbonElement as customElement } from '../../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element'; -import styles from './cloud-masthead.scss'; - -const { stablePrefix: c4dPrefix } = settings; - -/** - * Cloud Megamenu category link group - * - * @element c4d-cloud-megamenu-category-link-group - */ -@customElement(`${c4dPrefix}-cloud-megamenu-category-link-group`) -class C4DCloudMegaMenuCategoryLinkGroup extends LitElement { - render() { - return html` `; - } - - static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader -} - -export default C4DCloudMegaMenuCategoryLinkGroup; diff --git a/packages/web-components/src/components/masthead/cloud/cloud-megamenu-category-link.ts b/packages/web-components/src/components/masthead/cloud/cloud-megamenu-category-link.ts deleted file mode 100644 index be75ba2cb85..00000000000 --- a/packages/web-components/src/components/masthead/cloud/cloud-megamenu-category-link.ts +++ /dev/null @@ -1,46 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2020, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import { html } from 'lit'; -import { property } from 'lit/decorators.js'; -import CDSLink from '../../../internal/vendor/@carbon/web-components/components/link/link.js'; -import settings from '../../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import styles from './cloud-masthead.scss'; -import { carbonElement as customElement } from '../../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element.js'; - -const { stablePrefix: c4dPrefix } = settings; - -/** - * Cloud MegaMenu category link - * - * @element c4d-cloud-megamenu-category-link - */ -@customElement(`${c4dPrefix}-cloud-megamenu-category-link`) -class C4DCloudMegaMenuCateoryLink extends CDSLink { - /** - * link title. - */ - @property({ reflect: true }) - title = ''; - - /** - * @returns The inner content. - */ - protected _renderInner() { - const { title } = this; - return html` -

${title}

- - `; - } - - static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader -} - -export default C4DCloudMegaMenuCateoryLink; diff --git a/packages/web-components/src/components/masthead/cloud/cloud-megamenu-left-navigation.ts b/packages/web-components/src/components/masthead/cloud/cloud-megamenu-left-navigation.ts deleted file mode 100644 index 1fe862fdae5..00000000000 --- a/packages/web-components/src/components/masthead/cloud/cloud-megamenu-left-navigation.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2021, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import settings from '../../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import { carbonElement as customElement } from '../../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element'; -import C4DMegaMenuRightNavigation from '../megamenu-right-navigation'; -import styles from './cloud-masthead.scss'; - -const { stablePrefix: c4dPrefix } = settings; - -/** - * Cloud Megamenu Left Navigation Section. - * - * @element c4d-cloud-megamenu-left-navigation - */ -@customElement(`${c4dPrefix}-cloud-megamenu-left-navigation`) -class C4DCloudMegaMenuLeftNavigation extends C4DMegaMenuRightNavigation { - static styles = styles; -} - -export default C4DCloudMegaMenuLeftNavigation; diff --git a/packages/web-components/src/components/masthead/cloud/cloud-megamenu-right-navigation.ts b/packages/web-components/src/components/masthead/cloud/cloud-megamenu-right-navigation.ts deleted file mode 100644 index 4a11c709dc0..00000000000 --- a/packages/web-components/src/components/masthead/cloud/cloud-megamenu-right-navigation.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2021, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import settings from '../../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import { carbonElement as customElement } from '../../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element'; -import C4DMegaMenuLeftNavigation from '../megamenu-left-navigation'; -import styles from './cloud-masthead.scss'; - -const { stablePrefix: c4dPrefix } = settings; - -/** - * Cloud Megamenu Right Navigation Section. - * - * @element c4d-cloud-megamenu-right-navigation - */ -@customElement(`${c4dPrefix}-cloud-megamenu-right-navigation`) -class C4DCloudMegaMenuRightNavigation extends C4DMegaMenuLeftNavigation { - static styles = styles; -} - -export default C4DCloudMegaMenuRightNavigation; diff --git a/packages/web-components/src/components/masthead/cloud/cloud-megamenu-tab.ts b/packages/web-components/src/components/masthead/cloud/cloud-megamenu-tab.ts deleted file mode 100644 index 9755d1deda7..00000000000 --- a/packages/web-components/src/components/masthead/cloud/cloud-megamenu-tab.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2021, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import { html } from 'lit'; -import CDSTab from '../../../internal/vendor/@carbon/web-components/components/tabs/tab.js'; -import settings from '../../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import styles from './cloud-masthead.scss'; -import { carbonElement as customElement } from '../../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element.js'; - -const { prefix, stablePrefix: c4dPrefix } = settings; - -/** - * Cloud Megamenu Tab. - * - * @element c4d-cloud-megamenu-tab - */ -@customElement(`${c4dPrefix}-cloud-megamenu-tab`) -class C4DCloudMegaMenuTab extends CDSTab { - render() { - const { disabled, selected } = this; - return html` - - `; - } - - static styles = styles; -} - -export default C4DCloudMegaMenuTab; diff --git a/packages/web-components/src/components/masthead/cloud/cloud-megamenu-tabs.ts b/packages/web-components/src/components/masthead/cloud/cloud-megamenu-tabs.ts deleted file mode 100644 index 08fec50dc20..00000000000 --- a/packages/web-components/src/components/masthead/cloud/cloud-megamenu-tabs.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2021, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import CDSTabs from '../../../internal/vendor/@carbon/web-components/components/tabs/tabs.js'; -import settings from '../../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import styles from './cloud-masthead.scss'; -import { carbonElement as customElement } from '../../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element.js'; - -const { stablePrefix: c4dPrefix } = settings; - -/** - * Cloud Megamenu Tabs. - * - * @element c4d-cloud-megamenu-tabs - */ -@customElement(`${c4dPrefix}-cloud-megamenu-tabs`) -class C4DCloudMegaMenuTabs extends CDSTabs { - /** - * A selector that will return megamenu tabs. - */ - static get selectorItem() { - return `${c4dPrefix}-cloud-megamenu-tab`; - } - - /** - * A selector that will return selected items. - */ - static get selectorItemSelected() { - return `${c4dPrefix}-cloud-megamenu-tab[selected]`; - } - - static styles = styles; -} - -export default C4DCloudMegaMenuTabs; diff --git a/packages/web-components/src/components/masthead/cloud/cloud-megamenu.ts b/packages/web-components/src/components/masthead/cloud/cloud-megamenu.ts deleted file mode 100644 index efcebe81eee..00000000000 --- a/packages/web-components/src/components/masthead/cloud/cloud-megamenu.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2020, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import { html } from 'lit'; -import settings from '../../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import C4DMegaMenu from '../megamenu'; -import styles from './cloud-masthead.scss'; -import { carbonElement as customElement } from '../../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element'; - -const { prefix, stablePrefix: c4dPrefix } = settings; - -/** - * Cloud MegaMenu. - * - * @element c4d-cloud-megamenu - */ -@customElement(`${c4dPrefix}-cloud-megamenu`) -class C4DCloudMegaMenu extends C4DMegaMenu { - render() { - return html` -
-
- -
-
- `; - } - - static get stableSelector() { - return `${c4dPrefix}--masthead__megamenu`; - } - - static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader -} - -export default C4DCloudMegaMenu; diff --git a/packages/web-components/src/components/masthead/cloud/cloud-top-nav-name.ts b/packages/web-components/src/components/masthead/cloud/cloud-top-nav-name.ts deleted file mode 100644 index 031ebeb3d29..00000000000 --- a/packages/web-components/src/components/masthead/cloud/cloud-top-nav-name.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2021, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import settings from '../../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import { carbonElement as customElement } from '../../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element'; -import C4DTopNavName from '../top-nav-name'; -import styles from './cloud-masthead.scss'; - -const { stablePrefix: c4dPrefix } = settings; - -/** - * Cloud's brand name UI in top nav. - * - * @element c4d-cloud-top-nav-name - */ -@customElement(`${c4dPrefix}-cloud-top-nav-name`) -class C4DCloudTopNavName extends C4DTopNavName { - static styles = styles; -} - -export default C4DCloudTopNavName; diff --git a/packages/web-components/src/components/masthead/cloud/index.ts b/packages/web-components/src/components/masthead/cloud/index.ts deleted file mode 100644 index 48a379ec1a1..00000000000 --- a/packages/web-components/src/components/masthead/cloud/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2020, 2021 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import './cloud-masthead-container'; diff --git a/packages/web-components/src/components/masthead/defs.ts b/packages/web-components/src/components/masthead/defs.ts index 8082f0a9bd9..d1e31e834a7 100644 --- a/packages/web-components/src/components/masthead/defs.ts +++ b/packages/web-components/src/components/masthead/defs.ts @@ -47,26 +47,6 @@ export enum MEGAMENU_RIGHT_NAVIGATION_STYLE_SCHEME { HAS_SIDEBAR = 'has-sidebar', } -/** - * The style scheme for the right navigation. - */ -export enum LEGACY_MEGAMENU_RIGHT_NAVIGATION_STYLE_SCHEME { - /** - * Regular style. - */ - REGULAR = 'regular', - - /** - * For left (highlighted) section layout. - */ - LEFT_SECTION = 'left-section', - - /** - * For tabbed megamenus. - */ - TAB = 'tab', -} - /** * The layout options for rendering a megamenu */ diff --git a/packages/web-components/src/components/masthead/left-nav-cta-item.ts b/packages/web-components/src/components/masthead/left-nav-cta-item.ts deleted file mode 100644 index 827604f8471..00000000000 --- a/packages/web-components/src/components/masthead/left-nav-cta-item.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2022, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import { html } from 'lit'; -import settings from '../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import ArrowRight16 from '../../internal/vendor/@carbon/web-components/icons/arrow--right/16.js'; -import BXSideNavMenuItem from '../../internal/vendor/@carbon/web-components/components/ui-shell/side-nav-menu-item.js'; -import styles from './masthead.scss'; -import { carbonElement as customElement } from '../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element'; - -const { prefix, stablePrefix: c4dPrefix } = settings; - -/** - * Masthead left nav CTA item. - * - * @element c4d-left-nav-cta-item - */ -@customElement(`${c4dPrefix}-left-nav-cta-item`) -class C4DLeftNavCtaItem extends BXSideNavMenuItem { - render() { - const { href, title } = this; - return html` - - - - `; - } - - static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader -} - -export default C4DLeftNavCtaItem; diff --git a/packages/web-components/src/components/masthead/left-nav.ts b/packages/web-components/src/components/masthead/left-nav.ts index fb0e4463670..77bebe98c34 100644 --- a/packages/web-components/src/components/masthead/left-nav.ts +++ b/packages/web-components/src/components/masthead/left-nav.ts @@ -1,7 +1,7 @@ /** * @license * - * Copyright IBM Corp. 2020, 2023 + * Copyright IBM Corp. 2020, 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. @@ -252,14 +252,11 @@ class C4DLeftNav extends StableSelectorMixin(CDSSideNav) { const masthead: HTMLElement | null | undefined = doc ?.querySelector( - `${c4dPrefix}-cloud-masthead-container, - ${c4dPrefix}-cloud-masthead-composite, - ${c4dPrefix}-masthead-container, + `${c4dPrefix}-masthead-container, ${c4dPrefix}-masthead-composite` ) ?.querySelector(`${c4dPrefix}-masthead`); if (expanded && !this._importedSideNav) { - import('./left-nav-cta-item'); import('./left-nav-name'); import('./left-nav-menu'); import('./left-nav-menu-section'); diff --git a/packages/web-components/src/components/masthead/masthead-button-cta.ts b/packages/web-components/src/components/masthead/masthead-button-cta.ts deleted file mode 100644 index 0ff6e3c0a0a..00000000000 --- a/packages/web-components/src/components/masthead/masthead-button-cta.ts +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @license - * - * Copyright IBM Corp. 2022, 2023 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import BXButton from '../../internal/vendor/@carbon/web-components/components/button/button'; -import settings from '../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import { CTA_TYPE } from '../cta/defs'; -import styles from './masthead.scss'; -import { carbonElement as customElement } from '../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element'; - -export { CTA_TYPE }; - -const { stablePrefix: c4dPrefix } = settings; - -/** - * Masthead Button CTA. - * - * @element c4d--masthead-button-cta - */ -@customElement(`${c4dPrefix}-masthead-button-cta`) -class C4DMastheadButtonCTA extends BXButton { - static styles = styles; - - connectedCallback() { - super.connectedCallback(); - } -} - -export default C4DMastheadButtonCTA; diff --git a/packages/web-components/src/components/masthead/masthead-composite.ts b/packages/web-components/src/components/masthead/masthead-composite.ts index 96cd65c04ed..62eee269f7c 100644 --- a/packages/web-components/src/components/masthead/masthead-composite.ts +++ b/packages/web-components/src/components/masthead/masthead-composite.ts @@ -1,7 +1,7 @@ /** * @license * - * Copyright IBM Corp. 2020, 2023 + * Copyright IBM Corp. 2020, 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. @@ -29,7 +29,6 @@ import { L0Megamenu, Megapanel, MegapanelLinkGroup, - L1MenuItem, } from '../../internal/vendor/@carbon/ibmdotcom-services-store/types/translateAPI.d'; import { UNAUTHENTICATED_STATUS, @@ -43,7 +42,6 @@ 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'; import './masthead-l1-name'; import './masthead-menu-button'; @@ -71,21 +69,6 @@ import { carbonElement as customElement } from '../../internal/vendor/@carbon/we const { stablePrefix: c4dPrefix } = settings; -/** - * Rendering target for masthead navigation items. - */ -export enum NAV_ITEMS_RENDER_TARGET { - /** - * For top navigation. - */ - TOP_NAV = 'top-nav', - - /** - * For left navigation. - */ - LEFT_NAV = 'left-nav', -} - /** * Globally-scoped Contact Module variable. * @@ -118,24 +101,25 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { /** * Renders L1 menu based on l1Data & screen width. * - * @returns {TemplateResult | undefined} The L1 nav. + * @returns {TemplateResult | undefined} */ protected _renderL1() { - if (!this.l1Data) return undefined; - - return html` - - - `; + const { l1Data, selectedMenuItemL1 } = this; + return !l1Data + ? undefined + : html` + + + `; } /** * Renders masthead logo * - * @returns TemplateResult + * @returns {TemplateResult} A template fragment representing the logo. */ protected _renderLogo() { if (!this.logoData) { @@ -163,7 +147,7 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { * @param menu megamenu data object * @param _parentKey parent key * @param layout layout selection to render the megamenu with - * @returns TemplateResult + * @returns {TemplateResult} A template fragment representing a megamenu. */ // eslint-disable-next-line class-methods-use-this protected _renderMegaMenu( @@ -183,7 +167,7 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { * * @param menu megamenu data object * @param _parentKey key that identifies parent nav item - * @returns TemplateResult + * @returns {TemplateResult} A template fragment representing a tabbed megamenu. */ protected _renderMegaMenuTabbed(menu: L0Megamenu, _parentKey) { const { viewAll, sections } = menu; @@ -236,6 +220,12 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { `; } + /** + * Render individual tabpanel in a tabbed megamenu. + * + * @param menuItem menuItem data object + * @returns {TemplateResult} A template fragment representing a megamenu tabpanel. + */ protected _renderMegamenuTabPanel(menuItem) { const { itemKey, groups, heading, viewAll: itemViewAll } = menuItem; return html` @@ -285,7 +275,7 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { * * @param menu megamenu data object * @param _parentKey key that identifies parent nav item - * @returns TemplateResult + * @returns {TemplateResult} A template fragment representing a listing megamenu. */ // eslint-disable-next-line protected _renderMegaMenuListing(menu: L0Megamenu, _parentKey) { @@ -357,7 +347,7 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { * Render a Megapanel link group. * * @param group megamenu link group - * @returns TemplateResult + * @returns {TemplateResult} A template fragment representing a megapanel link group. */ // eslint-disable-next-line class-methods-use-this protected _renderMegapanelLinkGroup( @@ -408,7 +398,6 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { * Renders the left nav menus sections * * @param object heading heading of menu section - * @param object.ctas cta items * @param object.menuItems menu items * @param object.heading heading heading of menu section * @param object.isSubmenu determines whether menu section is a submenu section @@ -416,10 +405,11 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { * @param object.sectionTitle title of menu section * @param object.sectionUrl section title url of menu section * @param object.sectionId id of menu section + * @returns {TemplateResult} A template fragment representing the left nav menu + * sections. */ // eslint-disable-next-line class-methods-use-this protected _renderLeftNavMenuSections({ - ctas, menuItems, heading, isSubmenu = false, @@ -428,7 +418,7 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { sectionUrl = '', sectionId = '', }) { - const items = menuItems.map((elem) => { + const items = menuItems?.map((elem) => { if (elem.menu) { return html` { - items.push(html` - - ${cta.title} - - `); - }); - } - return html` { + const menuItems = this._getl0Data(); + const autoid = `${c4dPrefix}--masthead__l0`; + const level0Items = menuItems?.map((elem: L0MenuItem, i) => { // Instantiate bucket for first level submenus. const level1Items: { title: string; @@ -592,7 +575,6 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { if (level1Items.length !== 0) { menu.push( this._renderLeftNavMenuSections({ - ctas: undefined, menuItems: level1Items, isSubmenu: true, showBackButton: true, @@ -692,7 +674,6 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { if (level2Items.length !== 0) { menu.push( this._renderLeftNavMenuSections({ - ctas: undefined, menuItems: level2Items, isSubmenu: true, showBackButton: true, @@ -771,7 +752,6 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { menu.push( this._renderLeftNavMenuSections({ - ctas: undefined, menuItems: level1Items, isSubmenu: true, showBackButton: true, @@ -796,13 +776,42 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { }); return html` - ${this._renderLeftNavMenuSections({ - ctas: ctaButtons, - menuItems: level0Items, - sectionId: '-1, -1', - heading: false, - })} - ${menu} + + + ${!platform + ? undefined + : html` + + ${platform} + + `} + ${this._renderLeftNavMenuSections({ + menuItems: level0Items, + sectionId: '-1, -1', + heading: false, + })} + ${menu} + + `; + } + + /** + * Renders the mobile menu button. + * + * @returns {TemplateResult} A template fragment representing the menu button. + */ + protected _renderMenuButton() { + const { + activateSearch, + menuButtonAssistiveTextActive, + menuButtonAssistiveTextInactive, + } = this; + return html` + + `; } @@ -870,37 +879,24 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { } /** - * @param options The options. - * @param [options.selectedMenuItem] The selected nav item. - * @param options.target The target of rendering navigation items. - * @param options.hasL1 If an L1 menu is present - * @returns The nav items. - */ - protected _renderNavItems({ - target, - hasL1, - }: { - target: NAV_ITEMS_RENDER_TARGET; - hasL1: boolean; - }) { - const { navLinks, customNavLinks, l1Data } = this; - let menu: L0MenuItem[] | L1MenuItem[] | undefined = - customNavLinks || navLinks; - const autoid = `${c4dPrefix}--masthead__${l1Data?.menuItems ? 'l1' : 'l0'}`; - - if (hasL1) { - menu = l1Data?.menuItems; - } - - if (target === NAV_ITEMS_RENDER_TARGET.TOP_NAV) { - return !navLinks - ? undefined - : menu?.map((link, i) => { - return this._renderNavItem(link, i, autoid); - }); - } - - return !navLinks ? undefined : this._renderLeftNav(navLinks, autoid); + * Renders the top navigation bar. + * + * @returns {TemplateResult} A template fragment representing the top nav. + */ + protected _renderTopNav() { + const { selectedMenuItem, menuBarAssistiveText, activateSearch } = this; + return !this._getl0Data() + ? undefined + : html` + + ${this._getl0Data().map((link, i) => { + return this._renderNavItem(link, i, `${c4dPrefix}--masthead__l0`); + })} + + `; } /** @@ -909,7 +905,7 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { * @param item The item to render * @param i The index of the item in a series * @param autoid The unique id to assign to the item - * @returns A template fragment representing a nav item. + * @returns {TemplateResult} A template fragment representing a nav item. */ protected _renderNavItem(item: L0MenuItem, i, autoid): TemplateResult { const { selectedMenuItem, currentUrlPath, _activeMegamenuIndex } = this; @@ -1045,6 +1041,151 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { contactModuleApp?: CMApp; + /** + * Gets localized platform URL. + * + * @returns {string} A URL. + */ + private _getPlatformUrl(): string { + const { language, platformUrl } = this; + const formattedLang = language + ?.toLowerCase() + .replace(/-(.*)/, (m) => m.toUpperCase()); + let url = platformUrl; + if (platformUrl && formattedLang) { + if ( + typeof platformUrl === 'object' && + Object.prototype.hasOwnProperty.call(platformUrl, formattedLang) + ) { + url = platformUrl[formattedLang].url || platformUrl; + } + } + return url; + } + + /** + * Renders the platform title. + * + * @returns {TemplateResult} A template fragment representing the platform title. + */ + protected _renderPlatformTitle() { + const { l1Data, platform } = this; + return !platform || l1Data + ? undefined + : html` + + ${platform} + + `; + } + + /** + * Renders the masthead search. + * + * @returns {TemplateResult} A template fragment representing the search bar. + */ + protected _renderSearch() { + const { + activateSearch, + currentSearchResults, + customTypeaheadAPI, + hasSearch, + inputTimeout, + language, + openSearchDropdown, + scopeParameters, + searchPlaceholder, + } = this; + return hasSearch === 'false' + ? '' + : html` + + `; + } + + /** + * Renders the contact button. + * + * @returns {TemplateResult} A template fragment representing the contact button. + */ + protected _renderContact() { + const { contactUsButton, hasContact } = this; + return hasContact === 'false' + ? undefined + : html` + + `; + } + + /** + * Gets the appropriate profile items for the current masthead state. + * + * @returns An array of profile items or undefined. + */ + protected _getProfileItems(): MastheadProfileItem[] | undefined { + const { + customProfileLogin, + userIsAuthenticated, + authenticatedProfileItems, + unauthenticatedProfileItems, + } = this; + + let profileItems; + if ( + C4D_CUSTOM_PROFILE_LOGIN && + customProfileLogin && + !userIsAuthenticated + ) { + profileItems = unauthenticatedProfileItems?.map((item) => { + if (item?.id === 'signin') { + return { ...item, url: customProfileLogin }; + } + return item; + }); + } else { + profileItems = userIsAuthenticated + ? authenticatedProfileItems + : unauthenticatedProfileItems; + } + return profileItems; + } + + /** + * Renders the profile menu. + * + * @returns {TemplateResult} A template fragment representing the profile menu. + */ + protected _renderProfileMenu() { + const { hasProfile, userIsAuthenticated } = this; + return hasProfile === 'false' + ? '' + : html` + + ${this._getProfileItems()?.map( + ({ title, url }) => + html` + + ${title} + + ` + )} + + `; + } + /** * Whether or not a nav item has automatically been designated as "selected". * @@ -1133,12 +1274,6 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { @property({ attribute: false }) authenticatedProfileItems?: MastheadProfileItem[]; - /** - * The cta buttons for authenticated state. - */ - @property({ attribute: false }) - authenticatedCtaButtons?: MastheadProfileItem[]; - /** * Text for Contact us button */ @@ -1238,12 +1373,6 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { @property({ attribute: false }) unauthenticatedProfileItems?: MastheadProfileItem[]; - /** - * The cta buttons for authenticated state. - */ - @property({ attribute: false }) - unauthenticatedCtaButtons?: MastheadProfileItem[]; - /** * Specify translation endpoint if not using default c4d endpoint. */ @@ -1262,17 +1391,38 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { @property() language?: string; + /** + * Logo data + */ + @property({ attribute: false }) + logoData?: MastheadLogoData; + /** * The navigation links. + * + * @deprecated This property name is ambiguous. Use the l0Data prop instead. */ @property({ attribute: false }) navLinks?: L0MenuItem[]; /** - * Logo data + * Data for l0. */ @property({ attribute: false }) - logoData?: MastheadLogoData; + l0Data?: L0MenuItem[]; + + /** + * Temporary getter to fetch data until navLinks prop is phased out. + */ + private _getl0Data() { + const { l0Data, navLinks } = this; + if (navLinks) { + console.warn( + `Warning: ${c4dPrefix}-masthead's "navLinks" property is deprecated. Use "l0Data" property instead.` + ); + } + return (l0Data || navLinks) as L0MenuItem[]; + } /** * Data for l1. @@ -1304,12 +1454,6 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { @property({ attribute: 'auth-method' }) authMethod = MASTHEAD_AUTH_METHOD.DEFAULT; - /** - * Custom navigation links - */ - @property() - customNavLinks?: L0MenuItem[]; - /** * The user authentication status. */ @@ -1327,17 +1471,6 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { ); } - get ctaButtons(): MastheadProfileItem[] | undefined { - const { - userIsAuthenticated, - authenticatedCtaButtons, - unauthenticatedCtaButtons, - } = this; - return userIsAuthenticated - ? authenticatedCtaButtons - : unauthenticatedCtaButtons; - } - /** * A reference to the c4d-masthead element. */ @@ -1379,6 +1512,7 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { this.style.height = `${mastheadRef.getBoundingClientRect().height}px`; } } + firstUpdated() { const { language, dataEndpoint } = this; globalInit(); @@ -1425,176 +1559,26 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) { const { _isMobileVersion: isMobileVersion, activateSearch, - authenticatedProfileItems, - ctaButtons, - contactUsButton, - currentSearchResults, - customTypeaheadAPI, - customProfileLogin, - platform, - platformUrl, - hasProfile, - inputTimeout, - userIsAuthenticated, mastheadAssistiveText, - menuBarAssistiveText, - menuButtonAssistiveTextActive, - menuButtonAssistiveTextInactive, - navLinks, - customNavLinks, - language, - openSearchDropdown, - hasSearch, - scopeParameters, - searchPlaceholder, - selectedMenuItem, skipToContentText, skipToContentHref, - unauthenticatedProfileItems, - l1Data, - hasContact, } = this; - let profileItems; - if ( - C4D_CUSTOM_PROFILE_LOGIN && - customProfileLogin && - !userIsAuthenticated - ) { - profileItems = unauthenticatedProfileItems?.map((item) => { - if (item?.id === 'signin') { - return { ...item, url: customProfileLogin }; - } - return item; - }); - } else { - profileItems = userIsAuthenticated - ? authenticatedProfileItems - : unauthenticatedProfileItems; - } - const formattedLang = language - ?.toLowerCase() - .replace(/-(.*)/, (m) => m.toUpperCase()); - let platformAltUrl = platformUrl; - if (platformUrl && formattedLang) { - if ( - typeof platformUrl === 'object' && - Object.prototype.hasOwnProperty.call(platformUrl, formattedLang) - ) { - platformAltUrl = platformUrl[formattedLang].url || platformUrl; - } - } - return html` - ${isMobileVersion - ? html` - - - ${!platform - ? undefined - : html` - ${platform} - `} - ${this._renderNavItems({ - target: NAV_ITEMS_RENDER_TARGET.LEFT_NAV, - hasL1: !!l1Data, - })} - - ` - : ''} + ${isMobileVersion ? this._renderLeftNav() : ''} - - ${isMobileVersion - ? html` - - - ` - : ''} - ${this._renderLogo()} - ${!platform || l1Data - ? undefined - : html` - ${platform} - `} - ${(navLinks || customNavLinks) && !isMobileVersion - ? html` - - ${this._renderNavItems({ - target: NAV_ITEMS_RENDER_TARGET.TOP_NAV, - hasL1: false, - })} - - ` - : ''} - ${hasSearch === 'false' - ? '' - : html` - - `} + ${isMobileVersion ? this._renderMenuButton() : ''} ${this._renderLogo()} + ${this._renderPlatformTitle()} + ${!isMobileVersion ? this._renderTopNav() : ''} ${this._renderSearch()} - ${hasContact === 'false' - ? '' - : html` - - `} - ${hasProfile === 'false' - ? '' - : html` - - ${profileItems?.map( - ({ title, url }) => - html` - ${title} - ` - )} - - `} - ${ctaButtons?.map( - ({ title, url }) => - html` - - ${title} - - ` - )} + ${this._renderContact()} ${this._renderProfileMenu()} - ${!l1Data ? undefined : this._renderL1()} + ${this._renderL1()} `; diff --git a/packages/web-components/src/components/masthead/masthead-contact.ts b/packages/web-components/src/components/masthead/masthead-contact.ts index f37e399734c..228ff5e7756 100644 --- a/packages/web-components/src/components/masthead/masthead-contact.ts +++ b/packages/web-components/src/components/masthead/masthead-contact.ts @@ -1,7 +1,7 @@ /** * @license * - * Copyright IBM Corp. 2022, 2023 + * Copyright IBM Corp. 2022, 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. diff --git a/packages/web-components/src/components/masthead/masthead-container.ts b/packages/web-components/src/components/masthead/masthead-container.ts index 450e62c5e20..dccf53e6edd 100644 --- a/packages/web-components/src/components/masthead/masthead-container.ts +++ b/packages/web-components/src/components/masthead/masthead-container.ts @@ -1,7 +1,7 @@ /** * @license * - * Copyright IBM Corp. 2020, 2023 + * Copyright IBM Corp. 2020, 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. @@ -63,9 +63,9 @@ export interface MastheadContainerState { */ export interface MastheadContainerStateProps { /** - * The nav links. + * The L0 data. */ - navLinks?: L0MenuItem[]; + l0Data?: L0MenuItem[]; /** * The user authentication status. @@ -93,24 +93,42 @@ export function mapStateToProps( const { language } = localeAPI ?? {}; const { translations } = translateAPI ?? {}; const { request } = profileAPI ?? {}; + + // Attempt to collect data from current/new and deprecated locations. + let l0Data; + let profileItems; + if (language) { + l0Data = { + current: translations?.[language]?.masthead?.nav, + deprecated: translations?.[language]?.mastheadNav?.links, + }; + + profileItems = { + authenticated: { + current: translations?.[language]?.masthead?.profileMenu?.authenticated, + deprecated: translations?.[language]?.profileMenu?.signedin, + }, + unauthenticated: { + current: + translations?.[language]?.masthead?.profileMenu?.unauthenticated, + deprecated: translations?.[language]?.profileMenu?.signedout, + }, + }; + } + return pickBy( { - navLinks: !language - ? undefined - : translations?.[language]?.mastheadNav?.links, + // Progressively enhance to new L0 data shape. + l0Data: !language ? undefined : l0Data.current || l0Data.deprecated, + // Progressively enhance to new profile items shape. authenticatedProfileItems: !language ? undefined - : translations?.[language]?.profileMenu?.signedin, + : profileItems.authenticated.current || + profileItems.authenticated.deprecated, unauthenticatedProfileItems: !language ? undefined - : translations?.[language]?.profileMenu?.signedout, - authenticatedCtaButtons: !language - ? undefined - : translations?.[language]?.masthead?.profileMenu?.signedin?.ctaButtons, - unauthenticatedCtaButtons: !language - ? undefined - : translations?.[language]?.masthead?.profileMenu?.signedout - ?.ctaButtons, + : profileItems.unauthenticated.current || + profileItems.unauthenticated.deprecated, 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 7471e28597c..1ee8acd7040 100644 --- a/packages/web-components/src/components/masthead/masthead-l1.ts +++ b/packages/web-components/src/components/masthead/masthead-l1.ts @@ -1,7 +1,7 @@ /** * @license * - * Copyright IBM Corp. 2020, 2023 + * Copyright IBM Corp. 2020, 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. diff --git a/packages/web-components/src/components/masthead/masthead.scss b/packages/web-components/src/components/masthead/masthead.scss index 8bed59f8323..a1eb6e0e373 100644 --- a/packages/web-components/src/components/masthead/masthead.scss +++ b/packages/web-components/src/components/masthead/masthead.scss @@ -1,5 +1,5 @@ // -// Copyright IBM Corp. 2020, 2023 +// Copyright IBM Corp. 2020, 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. @@ -56,55 +56,6 @@ $breakpoint--desktop-nav: 799px; } } -:host(#{$c4d-prefix}-masthead-button-cta) { - @extend :host(#{$c4d-prefix}-button-cta); - - margin: 0; - padding-inline-end: 0; - - &.console .#{$prefix}--btn--ghost { - border-inline-start: 1px solid $button-separator; - color: $link-secondary; - } - - &:first-of-type { - .#{$prefix}--btn--ghost::before { - @include breakpoint-up(800px) { - position: absolute; - display: block; - background-color: $button-separator; - block-size: rem(24px); - content: ''; - inline-size: rem(1px); - inset-block-start: 50%; - inset-inline-start: 0; - transform: translateY(-50%); - } - } - } - - .#{$prefix}--btn { - padding: calc(0.875rem - 3px) rem(15px); - } - - .#{$prefix}--btn--ghost { - color: $link-primary; - @include type-style('body-short-02'); - - &:hover, - &:focus { - color: $link-secondary; - } - } -} - -:host(#{$c4d-prefix}-masthead-global-bar) - ::slotted(#{$c4d-prefix}-masthead-button-cta) { - @include breakpoint-down('md') { - display: none; - } -} - :host(#{$c4d-prefix}-masthead-logo) { @extend :host(#{$prefix}-header-name); @include masthead-logo; @@ -214,8 +165,7 @@ $breakpoint--desktop-nav: 799px; } :host(#{$c4d-prefix}-masthead-profile), -:host(#{$c4d-prefix}-masthead-contact), -:host(#{$c4d-prefix}-cloud-masthead-profile) { +:host(#{$c4d-prefix}-masthead-contact) { background-color: $background; inline-size: $spacing-09; @@ -308,8 +258,7 @@ $breakpoint--desktop-nav: 799px; :host(#{$c4d-prefix}-top-nav-menu), :host(#{$c4d-prefix}-megamenu-top-nav-menu), :host(#{$c4d-prefix}-masthead-profile), -:host(#{$c4d-prefix}-masthead-contact), -:host(#{$c4d-prefix}-cloud-masthead-profile) { +:host(#{$c4d-prefix}-masthead-contact) { // @extend :host(#{$prefix}-header-menu); position: relative; @@ -321,8 +270,7 @@ $breakpoint--desktop-nav: 799px; :host(#{$c4d-prefix}-top-nav-menu), :host(#{$c4d-prefix}-masthead-profile), -:host(#{$c4d-prefix}-masthead-contact), -:host(#{$c4d-prefix}-cloud-masthead-profile) { +:host(#{$c4d-prefix}-masthead-contact) { .#{$prefix}--header__menu-title[aria-expanded='true'] + .#{$prefix}--header__menu { background-color: $background; @@ -492,30 +440,10 @@ $breakpoint--desktop-nav: 799px; } } -:host(#{$c4d-prefix}-left-nav-menu-item), -:host(#{$c4d-prefix}-left-nav-cta-item) { +:host(#{$c4d-prefix}-left-nav-menu-item) { @extend :host(#{$prefix}-side-nav-menu-item); } -:host(#{$c4d-prefix}-left-nav-cta-item) { - @include breakpoint-up(md) { - display: none; - } - - a.#{$prefix}--side-nav__link .#{$prefix}--side-nav__link-text { - @include type-style(body-short-02, true); - - display: flex; - justify-content: space-between; - - color: $link-primary; - - > svg { - flex-shrink: 0; - } - } -} - :host(#{$c4d-prefix}-left-nav-item-highlighted) a.#{$prefix}--side-nav__link, :host(#{$c4d-prefix}-left-nav-menu-item-highlighted) a.#{$prefix}--side-nav__link, diff --git a/packages/web-components/src/components/masthead/megamenu-category-link-group.ts b/packages/web-components/src/components/masthead/megamenu-category-link-group.ts index d1e17e61b79..a5c54b1610c 100644 --- a/packages/web-components/src/components/masthead/megamenu-category-link-group.ts +++ b/packages/web-components/src/components/masthead/megamenu-category-link-group.ts @@ -15,7 +15,7 @@ import { carbonElement as customElement } from '../../internal/vendor/@carbon/we const { stablePrefix: c4dPrefix } = settings; /** - * Cloud Megamenu category link group + * Megamenu category link group * * @element c4d-megamenu-category-link-group */ diff --git a/packages/web-components/src/components/notice-choice/__stories__/README.stories.mdx b/packages/web-components/src/components/notice-choice/__stories__/README.stories.mdx index a284ac4ba41..2603df214a4 100644 --- a/packages/web-components/src/components/notice-choice/__stories__/README.stories.mdx +++ b/packages/web-components/src/components/notice-choice/__stories__/README.stories.mdx @@ -39,7 +39,6 @@ import '@carbon/ibmdotcom-web-components/es/components/notice-choice/index.js'; country="US" question-choices="1,2" state="CA" - email="" terms-condition-link="" bpid-legal-text="" enable-all-opt-in="" diff --git a/packages/web-components/src/components/notice-choice/__stories__/notice-choice.stories.ts b/packages/web-components/src/components/notice-choice/__stories__/notice-choice.stories.ts index 37881704a5d..5fd5cdb6717 100644 --- a/packages/web-components/src/components/notice-choice/__stories__/notice-choice.stories.ts +++ b/packages/web-components/src/components/notice-choice/__stories__/notice-choice.stories.ts @@ -71,7 +71,6 @@ const props = () => ({ country: select('Country', countryList, 'US'), state: select('State', stateList, ''), questionchoices: select('Question Choices', questionChoices, '1,2'), - email: text('Email', ''), termsConditionLink: text( 'Terms & Condition Link', 'https://www.ibm.com/legal' @@ -87,7 +86,6 @@ export const Default = (args) => { language, country, state, - email, termsConditionLink, questionchoices, hideErrorMessages, @@ -96,6 +94,8 @@ export const Default = (args) => { bpidLegalText, hiddenEmail, hiddenPhone, + ncTeleDetail, + ncEmailDetail, } = args?.NoticeChoice ?? {}; return html` { country="${country}" question-choices="${questionchoices}" state="${state}" - email=${email} terms-condition-link="${termsConditionLink || ''}" hide-error-message="${hideErrorMessages}" show-legal-notice=${showLegalNotice} @@ -111,6 +110,8 @@ export const Default = (args) => { bpid-legal-text="${bpidLegalText}" .hiddenEmail="${hiddenEmail}" .hiddenPhone="${hiddenPhone}" + .nc-tele-detail="${ncTeleDetail}" + .nc-email-detail="${ncEmailDetail}" @c4d-notice-choice-change=${onChange}> `; }; diff --git a/packages/web-components/src/components/notice-choice/notice-choice.ts b/packages/web-components/src/components/notice-choice/notice-choice.ts index 2d017e1c0f7..1269a737ce3 100644 --- a/packages/web-components/src/components/notice-choice/notice-choice.ts +++ b/packages/web-components/src/components/notice-choice/notice-choice.ts @@ -7,17 +7,15 @@ * LICENSE file in the root directory of this source tree. */ -import { checkPreferencesv3, loadContent } from './services'; +import { loadContent, loadSettings } from './services'; import { TemplateResult, html, LitElement } from 'lit'; import { property } from 'lit/decorators.js'; import { - emailRegExp, pwsValueMap, resetToWorldWideContent, supportedLanguages, - specialCountryBasedText, } from './utils'; -import countrySettings from './country-settings'; +// import this.countrySettings from './country-settings'; import settings from '../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; import StableSelectorMixin from '../../globals/mixins/stable-selector'; import styles from './notice-choice.scss'; @@ -64,9 +62,6 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { @property({ attribute: 'default-values' }) defaultValues = {}; - @property({ type: String, attribute: 'email' }) - email = ''; - @property({ type: Boolean, attribute: 'hide-error-message' }) hideErrorMessage = false; @@ -94,6 +89,15 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { @property({ type: Object, attribute: false }) isMandatoryCheckboxDisplayed = { countryCode: '', isDisplayed: false }; + @property({ type: Object, attribute: false }) + countrySettings: any; + + @property({ type: Boolean, attribute: false }) + emailPrechecked = false; + + @property({ type: Boolean, attribute: false }) + telephonePrechecked = false; + /** * End properties for passed attributes. */ @@ -121,6 +125,12 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { @property({ reflect: true }) hiddenPhone = ''; + @property({ reflect: true, attribute: 'nc-tele-detail' }) + ncTeleDetail = ''; + + @property({ reflect: true, attribute: 'nc-email-detail' }) + ncEmailDetail = ''; + prepareCheckboxes() { if (this.ncData) { const OptInContent = this.ncData; @@ -144,6 +154,16 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { } ); } + defaultLoadSettings() { + loadSettings( + (countryPreferencesSettings) => { + this.countrySettings = countryPreferencesSettings; + }, + (error) => { + console.error('error loading content', error); + } + ); + } connectedCallback() { super.connectedCallback(); const [language] = this.language.split(/[-_]/); @@ -166,6 +186,14 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { this.defaultLoadContent(); } ); + loadSettings( + (countryPreferencesSettings) => { + this.countrySettings = countryPreferencesSettings; + }, + () => { + this.defaultLoadSettings(); + } + ); } setDefaultSelections() { if (!this.enableAllOptIn && this.checkboxes) { @@ -199,11 +227,12 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { this.preventFormSubmission = false; if (this.ncData?.mandatoryCheckbox[this.country?.toLocaleLowerCase()]) { const countyCode = this.country?.toLocaleLowerCase(); - const countryBasedText = specialCountryBasedText(countyCode); - this._onChange( - this.ncData?.mandatoryCheckbox[countyCode][countryBasedText].mrs_field, - 'countyBasedCheckedNo' - ); + const mrsField = this.ncData?.mandatoryCheckbox[countyCode] + .countryTransferText + ? this.ncData?.mandatoryCheckbox[countyCode].countryTransferText + .mrs_field + : this.ncData?.mandatoryCheckbox[countyCode].chinaPIPLtext.mrs_field; + this._onChange(mrsField, 'countyBasedCheckedNo'); this.isMandatoryCheckboxDisplayed.countryCode = countyCode; this.isMandatoryCheckboxDisplayed.isDisplayed = true; @@ -279,7 +308,7 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { if ( hasValue && oldVal !== newVal && - countrySettings[newVal.toLocaleLowerCase()] + this.countrySettings[newVal.toLocaleLowerCase()] ) { this.countryChanged(); } @@ -288,23 +317,6 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { case 'enable-all-opt-in': this.setDefaultSelections(); break; - case 'email': { - if (newVal) { - if (newVal !== this.fetchedPref) { - // Handle throttle using debounce approach. - if (emailRegExp.test(newVal)) { - setTimeout(() => { - this.emailChanged(newVal); - }, 1000); - } - } - } else { - if (this.fetchedPref) { - this.fetchedPref = newVal; - } - } - break; - } case 'hide-error-message': { if (oldVal !== newVal) { this.hideErrorMessage = JSON.parse(newVal); @@ -335,6 +347,32 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { const hiddenFieldStatus = checked ? 'PERMISSION' : 'SUPPRESSION'; this.values[id] = {}; this.values[id]['checkBoxStatus'] = hiddenFieldStatus; + let statusPrechecked = ''; + switch (id) { + case 'EMAIL': + statusPrechecked = + this.emailPrechecked && !checked + ? 'CU' + : !this.emailPrechecked && checked + ? 'UC' + : this.emailPrechecked && checked + ? 'CC' + : 'UU'; + + break; + case 'PHONE': + statusPrechecked = + this.telephonePrechecked && checked + ? 'CC' + : this.telephonePrechecked && !checked + ? 'CU' + : !this.telephonePrechecked && checked + ? 'UC' + : 'UU'; + + break; + } + this.values[id]['punsStatus'] = statusPrechecked; this._onChange(hiddenFieldName, hiddenFieldStatus); this._onChange( `${hiddenFieldName}_VALUE`, @@ -358,18 +396,20 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { } const countyCode = this.country?.toLocaleLowerCase(); - const countryBasedText = specialCountryBasedText(countyCode); + const mrsField = this.ncData?.mandatoryCheckbox[countyCode] + .countryTransferText + ? this.ncData?.mandatoryCheckbox[ + this.isMandatoryCheckboxDisplayed.countryCode + ].countryTransferText.mrs_field + : this.ncData?.mandatoryCheckbox[countyCode].chinaPIPLtext.mrs_field; legalCheckbox.value = isChecked ? 1 : 0; this.preventFormSubmission = !isChecked; const preventFormSubmissionValue = isChecked ? 'formSubmissionYes' : 'formSubmissionNo'; this._onChange('preventFormSubmission', preventFormSubmissionValue); - this._onChange( - this.ncData?.mandatoryCheckbox[countyCode][countryBasedText].mrs_field, - countyBasedText - ); + this._onChange(mrsField, countyBasedText); } countryBasedLegalNotice() { @@ -525,16 +565,16 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { this.country.toLocaleLowerCase() !== this.isMandatoryCheckboxDisplayed.countryCode ) { - const countryBasedText = specialCountryBasedText( + const mrsField = this.ncData?.mandatoryCheckbox[ this.isMandatoryCheckboxDisplayed.countryCode - ); - - this._onChange( - this.ncData?.mandatoryCheckbox[ - this.isMandatoryCheckboxDisplayed.countryCode - ][countryBasedText].mrs_field, - 'countyBasedCheckedNo' - ); + ].countryTransferText + ? this.ncData?.mandatoryCheckbox[ + this.isMandatoryCheckboxDisplayed.countryCode + ].countryTransferText.mrs_field + : this.ncData?.mandatoryCheckbox[ + this.isMandatoryCheckboxDisplayed.countryCode + ].chinaPIPLtext.mrs_field; + this._onChange(mrsField, 'countyBasedCheckedNo'); } return html`

${ @@ -547,16 +587,40 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { Object.keys(this.checkboxes).map((key) => { const checked = this.values[key]; const checkbox = this.checkboxes[key]; + const punsStatus = this.values[key]['punsStatus'] + ? this.values[key]['punsStatus'] + : checked + ? 'CC' + : 'UU'; const hiddenBox = { id: 'NC_HIDDEN_' + key, value: this.values[key]['checkBoxStatus'] ? this.values[key]['checkBoxStatus'] : this.values[key] ? 'PERMISSION' - : 'UNCHANGED', + : 'SUPPRESSION', }; - key === 'EMAIL' ? (this.hiddenEmail = hiddenBox.value) : ''; - key === 'PHONE' ? (this.hiddenPhone = hiddenBox.value) : ''; + switch (key) { + case 'EMAIL': + this.hiddenEmail = hiddenBox.value; + this.ncEmailDetail = punsStatus; + if (typeof checked !== 'object') { + this.emailPrechecked = checked ? true : false; + } + break; + case 'PHONE': + this.hiddenPhone = hiddenBox.value; + this.ncTeleDetail = punsStatus; + if (typeof checked !== 'object') { + this.telephonePrechecked = checked ? true : false; + } + break; + } + const punsValue = key === 'PHONE' ? 'TELE' : key; + this._onChange( + `NC_${punsValue}_DETAIL`, + `${key}_${punsStatus}` + ); return this.checkBoxTemplate(checkbox, checked, hiddenBox); }) : '' @@ -572,38 +636,10 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { ${this.getBpidLegalText()}

`; } - protected emailChanged(email) { - if (this.changed === false) { - checkPreferencesv3(email).then((response) => { - const questionChoiceStatus = - countrySettings[this.country.toLocaleLowerCase()]; - - if (response === 'S' && questionChoiceStatus.email === 'opt-out') { - this.values = { - ...this.values, - EMAIL: false, - ...{ checkBoxStatus: 'UNCHANGED' }, - }; - this._onChange('NC_HIDDEN_EMAIL', null); - } else { - this.values = { - ...this.values, - EMAIL: questionChoiceStatus.email === 'opt-out' ? true : false, - ...{ - checkBoxStatus: - questionChoiceStatus.email === 'opt-out' - ? 'PERMISSION' - : 'UNCHANGED', - }, - }; - this._onChange('NC_HIDDEN_EMAIL', null); - } - }); - } - } + protected _getOptionByQuestion = (question) => { const questionChoiceStatus = this.country - ? countrySettings[this.country.toLocaleLowerCase()] + ? this.countrySettings[this.country.toLocaleLowerCase()] : { email: 'opt-in', phone: 'opt-in' }; let option; @@ -674,8 +710,17 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { NC_HIDDEN_PHONE: 'permission_phone', preventFormSubmission: 'preventFormSubmission', Q_CHINA_PIPL: 'Q_CHINA_PIPL', + Q_COUNTRY_TRANSFER: 'Q_COUNTRY_TRANSFER', NC_HIDDEN_EMAIL_VALUE: 'NC_HIDDEN_EMAIL', NC_HIDDEN_PHONE_VALUE: 'NC_HIDDEN_PHONE', + EMAIL_CU: 'EMAIL_CU', + EMAIL_CC: 'EMAIL_CC', + EMAIL_UC: 'EMAIL_UC', + EMAIL_UU: 'EMAIL_UU', + PHONE_CU: 'PHONE_CU', + PHONE_CC: 'PHONE_CC', + PHONE_UC: 'PHONE_UC', + PHONE_UU: 'PHONE_UU', }; if (Object.prototype.hasOwnProperty.call(pwsFieldsMap, field)) { diff --git a/packages/web-components/src/components/notice-choice/services.ts b/packages/web-components/src/components/notice-choice/services.ts index 7ba81d827f5..96a3a957b8a 100644 --- a/packages/web-components/src/components/notice-choice/services.ts +++ b/packages/web-components/src/components/notice-choice/services.ts @@ -4,28 +4,7 @@ * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ -import axios from 'axios'; -export function checkPreferencesv3(emailAddress) { - const endpoint = `https://www.ibm.com/account/apis/v2.0/pws/V3.0/lookup`; - return new Promise((resolve, reject) => { - if (emailAddress && emailAddress.indexOf('*****') > -1) { - resolve('N'); - } else { - axios - .get(endpoint, { - params: { emailAddress }, - }) - .then((response) => { - resolve(response.data ? response.data.email : 'N'); - }) - .catch((error) => { - console.error(error); - reject('N'); - }); - } - }); -} export function loadContent(locale: string, onSuccess: any, onError: any) { const script = document.createElement('script'); script.async = false; @@ -49,3 +28,27 @@ export function loadContent(locale: string, onSuccess: any, onError: any) { } }; } + +export function loadSettings(onSuccess: any, onError: any) { + const script = document.createElement('script'); + script.async = false; + script.charset = 'utf-8'; + script.src = `https://1.www.s81c.com/common/noticechoice/settings.js`; // URL for the third-party library being loaded. + document.body.appendChild(script); + script.onload = () => { + try { + if (onSuccess) { + onSuccess(window.NoticeChoice.settings?.preferences); + } + } catch (e) { + if (onError) { + onError(e); + } + } + }; + script.onerror = () => { + if (onError) { + onError(); + } + }; +} diff --git a/packages/web-components/src/components/notice-choice/utils.ts b/packages/web-components/src/components/notice-choice/utils.ts index 00e2281a0de..506ea962188 100644 --- a/packages/web-components/src/components/notice-choice/utils.ts +++ b/packages/web-components/src/components/notice-choice/utils.ts @@ -63,18 +63,18 @@ export function pwsValueMap(value) { countyBasedCheckedNo: 'false', NC_HIDDEN_PERMISSION: 'PERMISSION', NC_HIDDEN_SUPPRESSION: 'SUPPRESSION', - NC_HIDDEN_UNCHANGED: 'UNCHANGED', + EMAIL_CU: 'CU', + EMAIL_CC: 'CC', + EMAIL_UU: 'UU', + EMAIL_UC: 'UC', + PHONE_CU: 'CU', + PHONE_CC: 'CC', + PHONE_UC: 'UC', + PHONE_UU: 'UU', }[value] || null ); } -export function specialCountryBasedText(countryCode) { - const countryBasedText = { - cn: 'chinaPIPLtext', - }; - return countryBasedText[countryCode.toLocaleLowerCase()]; -} - export function supportedLanguages(language) { const languageMapping = { en: 'en', diff --git a/packages/web-components/src/components/search-with-typeahead/search-with-typeahead.ts b/packages/web-components/src/components/search-with-typeahead/search-with-typeahead.ts index 658dc82964a..364c6dd8bcf 100644 --- a/packages/web-components/src/components/search-with-typeahead/search-with-typeahead.ts +++ b/packages/web-components/src/components/search-with-typeahead/search-with-typeahead.ts @@ -1,7 +1,7 @@ /** * @license * - * Copyright IBM Corp. 2019, 2023 + * Copyright IBM Corp. 2019, 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. @@ -27,6 +27,7 @@ import styles from './search-with-typeahead.scss'; import StableSelectorMixin from '../../globals/mixins/stable-selector'; import './search-with-typeahead-item'; import { carbonElement as customElement } from '../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element.js'; +import C4DSearchWithTypeaheadItem from './search-with-typeahead-item'; const { prefix, stablePrefix: c4dPrefix } = settings; const gridBreakpoint = parseFloat(breakpoints.lg.width) * baseFontSize; @@ -157,9 +158,7 @@ class C4DSearchWithTypeahead extends HostListenerMixin( } /** - * Handles `click` event on the top-level element in the shadow DOM. - * - * @param event The event. + * @inheritdoc */ protected _handleClickInner(event: MouseEvent) { if ( @@ -167,7 +166,7 @@ class C4DSearchWithTypeahead extends HostListenerMixin( event.target ) { this._handleUserInitiatedToggle(); - if (this._searchInputNode.value && this.leadspaceSearch) { + if (this.searchQueryString && this.leadspaceSearch) { this._closeButtonNode?.classList.remove( `${prefix}--header__search--hide` ); @@ -189,7 +188,7 @@ class C4DSearchWithTypeahead extends HostListenerMixin( const { active } = this; if (active) { - if (this._searchInputNode.value) { + if (this.searchQueryString) { this._handleUserInitiatedRedirect(); } } else { @@ -263,6 +262,36 @@ class C4DSearchWithTypeahead extends HostListenerMixin( } } + /** + * Builds a redirect href string with appropriate query params. Emulates what + * would be generated by the form action. + * + * @param targetQuery An optional query string value. + * @returns {string} An href string. + */ + private _buildRedirect(targetQuery: string = this.searchQueryString) { + const [primary, country] = this.language.split('-'); + const tokens = this.redirectUrl.split('?'); + const base = tokens.shift(); + const searchParams = new URLSearchParams(tokens.join('?')); + // Setting `this.searchQueryString` as the default value of `targetQuery` seems to cause a Babel bug + searchParams.append('q', targetQuery); + searchParams.append('lang', primary); + searchParams.append('cc', country); + + if (this.appId) { + searchParams.append('scope-domain', 'scope'); + searchParams.append('scope-value', this.scopeValue); + searchParams.append('scope-type', this.appId); + + if (this.scopeLabel) { + searchParams.append('scope-label', this.scopeLabel ?? ''); + } + } + + return `${base}?${searchParams.toString()}`; + } + /** * Handles user-initiated redirect to the search query page. * @@ -276,15 +305,6 @@ class C4DSearchWithTypeahead extends HostListenerMixin( }: { targetQuery?: string; targetHref?: string } = {}) { const { eventBeforeRedirect, eventInput } = this .constructor as typeof C4DSearchWithTypeahead; - const { language, redirectUrl } = this; - const [primary, country] = language.split('-'); - const tokens = redirectUrl.split('?'); - const base = tokens.shift(); - const searchParams = new URLSearchParams(tokens.join('?')); - // Setting `this._searchInputNode?.value` as the default value of `targetQuery` seems to cause a Babel bug - searchParams.append('q', targetQuery ?? this._searchInputNode?.value); - searchParams.append('lang', primary); - searchParams.append('cc', country); this.dispatchEvent( new CustomEvent(eventInput, { @@ -297,19 +317,9 @@ class C4DSearchWithTypeahead extends HostListenerMixin( }) ); - if (this.appId) { - searchParams.append('scope-domain', 'scope'); - searchParams.append('scope-value', this.scopeValue); - searchParams.append('scope-type', this.appId); + const query = targetQuery ?? this.searchQueryString; - if (this.scopeLabel) { - searchParams.append('scope-label', this.scopeLabel ?? ''); - } - } - - const redirectUrlWithSearch = targetHref - ? `${targetHref}` - : `${base}?${searchParams.toString()}`; + const redirectUrlWithSearch = targetHref || this._buildRedirect(query); if ( this.dispatchEvent( new CustomEvent(eventBeforeRedirect, { @@ -318,6 +328,7 @@ class C4DSearchWithTypeahead extends HostListenerMixin( composed: true, detail: { redirectUrl: redirectUrlWithSearch, + searchQueryString: query, }, }) ) @@ -327,9 +338,7 @@ class C4DSearchWithTypeahead extends HostListenerMixin( } /** - * Handles component reset if focusing outside. - * - * @param event The event. + * @inheritdoc */ @HostListener('focusout') // @ts-ignore: The decorator refers to this method but TS thinks this method is not referred to @@ -449,29 +458,36 @@ class C4DSearchWithTypeahead extends HostListenerMixin( } /** - * Prevents form submission if there is a highlighted item. - * In such case, `._handleUserInitiatedRedirect()` should have navigated the user to the search result page. + * Handles search form submission and cancels event execution in circumstances + * where user action is handled elsewhere. * - * @param event The event. + * @param event The form submission event. */ private _handleSubmit(event: Event) { + const { searchQueryString, redirectUrl } = this; const { eventBeforeRedirect } = this .constructor as typeof C4DSearchWithTypeahead; const { selectorItemHighlighted } = this.constructor as typeof CDSDropdown; const highlightedItem = this.shadowRoot!.querySelector( selectorItemHighlighted ) as CDSDropdownItem; - if (highlightedItem || !this._searchInputNode.value) { + + // Prevents form submission in certain circumstances. In the case where there + // is a highlighted item, `._handleUserInitiatedRedirect()` should have navigated + // the user to the search result page. + // Otherwise, gives users an opportunity to react to the event before + // executing the form's action. + if (highlightedItem || !searchQueryString) { event.preventDefault(); - } - if ( + } else if ( !this.dispatchEvent( new CustomEvent(eventBeforeRedirect, { bubbles: true, cancelable: true, composed: true, detail: { - redirectUrl: this.redirectUrl, + redirectUrl, + searchQueryString, }, }) ) @@ -480,18 +496,23 @@ class C4DSearchWithTypeahead extends HostListenerMixin( } } - protected _handleUserInitiatedSelectItem(item?: CDSDropdownItem) { - if (item) { - this._searchInputNode.value = (item as unknown as any).text; + /** + * @inheritdoc + */ + protected _handleUserInitiatedSelectItem( + item?: CDSDropdownItem | C4DSearchWithTypeaheadItem + ) { + if (item && item instanceof C4DSearchWithTypeaheadItem) { + this._searchInputNode.value = item.text; this._handleUserInitiatedRedirect({ - targetQuery: (item as unknown as any).text, - targetHref: (item as unknown as any).href, + targetQuery: item.text, + targetHref: item.href, }); } } /** - * Handler for the `keypress` event on the top-level element in the shadow DOM. + * @inheritdoc */ protected _handleKeypressInner(event: KeyboardEvent) { const { key } = event; @@ -508,9 +529,10 @@ class C4DSearchWithTypeahead extends HostListenerMixin( switch (action) { case DROPDOWN_KEYBOARD_ACTION.TRIGGERING: { - const constructor = this.constructor as typeof CDSDropdown; + const { selectorItemHighlighted } = this + .constructor as typeof CDSDropdown; const highlightedItem = this.shadowRoot!.querySelector( - constructor.selectorItemHighlighted + selectorItemHighlighted ) as CDSDropdownItem; if (highlightedItem) { this._handleUserInitiatedSelectItem(highlightedItem); @@ -611,8 +633,9 @@ class C4DSearchWithTypeahead extends HostListenerMixin( * @param event The event. */ protected _handleClickItem(event: MouseEvent) { + const { selectorItem } = this.constructor as typeof CDSDropdown; const item = (event.target as Element).closest( - (this.constructor as typeof CDSDropdown).selectorItem + selectorItem ) as CDSDropdownItem; if (this.shadowRoot!.contains(item)) { this._handleUserInitiatedSelectItem(item); diff --git a/packages/web-components/src/globals/internal/feature-flags.ts b/packages/web-components/src/globals/internal/feature-flags.ts index 409f5adcc4e..e42cb59820d 100644 --- a/packages/web-components/src/globals/internal/feature-flags.ts +++ b/packages/web-components/src/globals/internal/feature-flags.ts @@ -45,14 +45,6 @@ export const C4D_CONTENT_BLOCK_CARD_STATIC: boolean = export const C4D_SCOPED_SEARCH: boolean = process!.env.C4D_SCOPED_SEARCH === 'true' || C4D_FLAGS_ALL || false; -/** - * Enables Cloud Masthead Components - * - * @type {boolean} - */ -export const C4D_CLOUD_MASTHEAD: boolean = - process!.env.C4D_CLOUD_MASTHEAD === 'true' || C4D_FLAGS_ALL || false; - /** * Enables custom profile login url in Masthead * diff --git a/packages/web-components/tests/e2e-storybook/cypress/integration/link-with-icon/default.e2e.js b/packages/web-components/tests/e2e-storybook/cypress/integration/link-with-icon/default.e2e.js index b8fcc74e0d0..686344d4b6f 100644 --- a/packages/web-components/tests/e2e-storybook/cypress/integration/link-with-icon/default.e2e.js +++ b/packages/web-components/tests/e2e-storybook/cypress/integration/link-with-icon/default.e2e.js @@ -1,5 +1,5 @@ /** - * Copyright IBM Corp. 2021, 2022 + * Copyright IBM Corp. 2021, 2023 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. @@ -15,13 +15,19 @@ */ const _path = '/iframe.html?id=components-link-with-icon--default'; +const _videoId = '0_ibuqxqbe'; + +const _videoPath = `/iframe.html?&id=components-link-with-icon--default&knob-CTA%20type%20(cta-type)=video&knob-Icon%20Position%20(icon-placement):=right&knob-Video%20ID%20(href)=${_videoId}`; + /** * Defines the component selector. * * @type {string} * @private */ -const _selector = '[data-autoid="cds--link-with-icon"]'; +const _selector = '[data-autoid="c4d--link-with-icon"]'; + +const _lightboxVideoPlayerSelector = 'c4d-lightbox-video-player'; /** * Collection of test scenarios. @@ -47,7 +53,9 @@ const _tests = [ .then(([copy]) => { defaultCopy = copy.innerText.trim(); }) - .visit(`${_path}&knob-Link%20text%20(unnamed%20slot)=${customCopyInput}`) + .visit( + `${_path}&knob-Link%20text%20(unnamed%20slot)=${customCopyInput}` + ) .get(_selector) .should(([copy]) => { customCopyOutput = copy.innerText.trim(); @@ -66,16 +74,18 @@ const _tests = [ .get(_selector) .shadow() .find('a') - .should($link => { + .should(($link) => { defaultHref = $link.prop('href'); expect($link.prop('href')).not.to.be.empty; }) - .visit(`${_path}&knob-Link%20href%20(href)=${customHrefInput}`) + .visit( + `${_path}&knob-Content%20link%20href%20(href)=${customHrefInput}` + ) .get(_selector) .shadow() .find('a') - .should($link => { + .should(($link) => { customHrefOutput = $link.prop('href'); expect(customHrefOutput).to.be.eq(customHrefInput); @@ -94,16 +104,18 @@ const _tests = [ }, () => { it('should check icon placements', () => { - ['left', 'right'].forEach(placement => { + ['left', 'right'].forEach((placement) => { let $svg; - cy.visit(`${_path}&knob-Icon%20Position%20(icon-placement):=${placement}`) + cy.visit( + `${_path}&knob-Icon%20Position%20(icon-placement):=${placement}` + ) .get(_selector) - .then($elem => { + .then(($elem) => { $svg = $elem.find('svg'); }) .shadow() .find('a') - .should($link => { + .should(($link) => { const svgPosition = $svg[0].getBoundingClientRect(); const textPosition = $link.find('span')[0].getBoundingClientRect(); @@ -123,6 +135,21 @@ const _tests = [ }); }); }, + () => { + it('should replace the button title with the video title for a video cta type', () => { + cy.visit(_videoPath); + cy.get(_selector) + .shadow() + .find('a > span') + .should('contain.text', 'Mombo'); + cy.get(_lightboxVideoPlayerSelector).should('not.exist'); + }); + + it('should trigger the lightbox for video when using the right URL fragment', () => { + cy.visit(`${_videoPath}#cta-video-${_videoId}`); + cy.get(_lightboxVideoPlayerSelector).should('exist').and('be.visible'); + }); + }, ]; describe('cds-link-with-icon | default (desktop)', () => { @@ -130,7 +157,7 @@ describe('cds-link-with-icon | default (desktop)', () => { cy.viewport(1280, 780); }); - _tests.forEach(test => test()); + _tests.forEach((test) => test()); }); describe('cds-link-with-icon | default (mobile)', () => { @@ -138,5 +165,5 @@ describe('cds-link-with-icon | default (mobile)', () => { cy.viewport(375, 720); }); - _tests.forEach(test => test()); + _tests.forEach((test) => test()); }); diff --git a/packages/web-components/tests/snapshots/c4d-masthead-composite.md b/packages/web-components/tests/snapshots/c4d-masthead-composite.md index 91676967afe..9e32e442d92 100644 --- a/packages/web-components/tests/snapshots/c4d-masthead-composite.md +++ b/packages/web-components/tests/snapshots/c4d-masthead-composite.md @@ -6,7 +6,15 @@ ``` + + + + My IBM + Log in @@ -19,6 +27,11 @@ ``` + + - ``` #### `should render the given nav items to the left` @@ -111,6 +123,5 @@
- ``` diff --git a/packages/web-components/tests/snapshots/cds-masthead-composite.md b/packages/web-components/tests/snapshots/cds-masthead-composite.md deleted file mode 100644 index bcebce88a7f..00000000000 --- a/packages/web-components/tests/snapshots/cds-masthead-composite.md +++ /dev/null @@ -1,55 +0,0 @@ -# `cds-masthead-composite` - -## `Rendering global bar` - -#### `should render unauthenticated state` - -``` - - - - - - My IBM - - - Log in - - - - -``` - -#### `should render authenticated state` - -``` - - - - - - My IBM - - - Profile - - - Billing - - - Log out - - - - -``` - diff --git a/packages/web-components/tests/snapshots/dds-masthead-composite.md b/packages/web-components/tests/snapshots/dds-masthead-composite.md deleted file mode 100644 index 1113ff64081..00000000000 --- a/packages/web-components/tests/snapshots/dds-masthead-composite.md +++ /dev/null @@ -1,54 +0,0 @@ -# `dds-masthead-composite` - -## `Rendering global bar` - -#### `should render unauthenticated state` - -``` - - - - - - My IBM - - - Log in - - - - -``` - -#### `should render authenticated state` - -``` - - - - - - My IBM - - - Profile - - - Billing - - - Log out - - - - -``` diff --git a/packages/web-components/tools/get-rollup-config.js b/packages/web-components/tools/get-rollup-config.js index 5d4db514708..859baa9df7b 100644 --- a/packages/web-components/tools/get-rollup-config.js +++ b/packages/web-components/tools/get-rollup-config.js @@ -1,7 +1,7 @@ /** * @license * - * Copyright IBM Corp. 2020, 2023 + * Copyright IBM Corp. 2020, 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. @@ -103,10 +103,6 @@ function getRollupConfig({ `ibmdotcom-web-components-dotcom-shell${dirSuffixes[dir]}${modeSuffixes[mode]}` ] = 'src/components/dotcom-shell/index.ts'; - // adding the cloud masthead - inputs[`cloud-masthead${dirSuffixes[dir]}${modeSuffixes[mode]}`] = - 'src/components/masthead/cloud/index.ts'; - folders.forEach((folder) => { if (folder === 'cta') { inputs[