Skip to content

Commit

Permalink
feat(masthead): support all CMaaS CTA types for L1 CTA (#11597)
Browse files Browse the repository at this point in the history
none

Supports rendering the appropriate markup to integrate with all CTA types supported by the IBM Contact Module app (documented here: https://github.ibm.com/live-advisor/cm-app/blob/master/docs/cm-doc.md#calls-to-action).

> **Note:** You may need to use Requestly or a similar service to trick the Contact Module into working on a non-ibm.com webpage. I've attached my Requestly override rule below for reference.

Visit the [Masthead with L1 deploy preview](https://ibmdotcom-webcomponents.s3.us-east.cloud-object-storage.appdomain.cloud/deploy-previews/11597/index.html?path=/story/components-masthead--with-l-1). For each L1 CTA knob option, verify:
- The L1 CTA's icon changes.
- The Contact Module changes the CTA text
   - You'll need to open the Story in a new tab to see this in effect. This is a CMApp limitation.
- Clicking the CTA activates the Contact Module. For example, setting the CTA type to "scheduler" should open a "Book a meeting" panel.

<img width="1029" alt="Screenshot 2024-03-04 at 9 30 01 AM" src="https://github.com/carbon-design-system/carbon-for-ibm-dotcom/assets/12532727/02524ba7-a0fb-41d2-ad18-8512fd815f91">
<img width="1029" alt="Screenshot 2024-03-04 at 9 30 11 AM" src="https://github.com/carbon-design-system/carbon-for-ibm-dotcom/assets/12532727/6cc834b0-90a7-49ea-bc5d-617f57d2b771">

**New**

- Adds ability to configure L1 CTA to integrate with each of the supported IBM Contact Module app CTA types.
- Creates `<c4d-masthead-l1-cta>` component that renders markup required for Contact Module integrations.

**Changed**

- Removes `<c4d-masthead-composite>`'s shadow root to enable Contact Module integrations.

<!-- React and Web Component deploy previews are enabled by default. -->
<!-- To enable additional available deploy previews, apply the following -->
<!-- labels for the corresponding package: -->
<!-- *** "test: e2e": Codesandbox examples and e2e integration tests -->
<!-- *** "package: services": Services -->
<!-- *** "package: utilities": Utilities -->
<!-- *** "RTL": React / Web Components (RTL) -->
<!-- *** "feature flag": React / Web Components (experimental) -->
  • Loading branch information
jkaeser authored and kennylam committed Mar 20, 2024
1 parent 297fca5 commit 2f8fccf
Show file tree
Hide file tree
Showing 8 changed files with 313 additions and 157 deletions.
108 changes: 57 additions & 51 deletions packages/styles/scss/components/masthead/_masthead-l1.scss
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ $search-transition-timing: 95ms;

@mixin masthead-l1 {
// Set up variables to store column-widths without using flexbox

.#{$prefix}--masthead__l1,
:host(#{$c4d-prefix}-masthead-l1) {
/* stylelint-disable-next-line length-zero-no-unit */
Expand Down Expand Up @@ -337,33 +336,35 @@ $search-transition-timing: 95ms;
}
}

.#{$prefix}--masthead__l1-dropdown-cta {
@include mobile-button-base;
@include type-style(body-short-01);
:host(#{$c4d-prefix}-masthead-l1-cta) {
.#{$prefix}--masthead__l1-dropdown-cta {
@include mobile-button-base;
@include type-style(body-short-01);

background-color: $background-brand;
color: $layer-02;
background-color: $background-brand;
color: $layer-02;

svg {
color: inherit;
}
svg {
color: inherit;
}

&:hover {
background-color: $button-primary-hover;
}
&:hover {
background-color: $button-primary-hover;
}

&:focus-visible {
outline-color: $layer-02;
outline-offset: calc(-1 * #{$spacing-02});
}
&:focus-visible {
outline-color: $layer-02;
outline-offset: calc(-1 * #{$spacing-02});
}

&:active {
background-color: $button-primary-active;
color: $layer-02;
}
&:active {
background-color: $button-primary-active;
color: $layer-02;
}

&:disabled {
background-color: $text-disabled;
&:disabled {
background-color: $text-disabled;
}
}
}
}
Expand Down Expand Up @@ -817,43 +818,48 @@ $search-transition-timing: 95ms;
}
}

.#{$prefix}--masthead__l1-cta {
@include desktop-button-base;
@include type-style(body-short-01);

display: inline-flex;
align-items: flex-end;
background-color: $background-brand;
color: $layer-02;
:host(#{$c4d-prefix}-masthead-l1-cta) {
position: relative;
z-index: 1;
grid-area: cta;

svg {
color: inherit;
}
.#{$prefix}--masthead__l1-cta {
@include desktop-button-base;
@include type-style(body-short-01);

&:hover {
background-color: $button-primary-hover;
}
display: inline-flex;
align-items: flex-end;
background-color: $background-brand;
color: $layer-02;

&:focus-visible {
outline: $spacing-01 solid $layer-02;
outline-offset: calc(-1 * #{$spacing-01});
}
svg {
color: inherit;
}

&:active {
background-color: $button-primary-active;
color: $layer-02;
}
&:hover {
background-color: $button-primary-hover;
}

&:disabled {
background-color: $text-disabled;
&:focus-visible {
outline: $spacing-01 solid $layer-02;
outline-offset: calc(-1 * #{$spacing-01});
}

&:active {
background-color: $button-primary-active;
color: $layer-02;
}

&:disabled {
background-color: $text-disabled;
}
}
}

.#{$prefix}--masthead__l1-cta-inner {
display: inline-flex;
align-items: center;
gap: $spacing-03;
.#{$prefix}--masthead__l1-cta-inner {
display: inline-flex;
align-items: center;
gap: $spacing-03;
}
}

.#{$prefix}--masthead__l1-login {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,40 @@ const l1Data = {
document.getElementById('masthead').l1Data = l1Data;
```

#### L1 CTA

By default, the L1 CTA renders as a button link.

```javascript
const l1Data = {
platform: {...}
menuItems: [...],
actions: {
cta: {
title: 'Link text',
url: 'https://www.example.com',
},
},
}
```

You can also set a `ctaType` to render as a button that will integrate with the IBM Contact Module application on supported domains. Available CTA types are defined by the `L1_CTA_TYPES` enum in [the definitions file](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/blob/main/packages/web-components/src/components/masthead/defs.ts)

> See the [Contact Module as a Service (CMaaS) documentation](https://github.ibm.com/live-advisor/cm-app/blob/master/docs/cm-doc.md#calls-to-action) for more information.
```javascript
const l1Data = {
platform: {...}
menuItems: [...],
actions: {
cta: {
title: 'Chat now',
ctaType: 'chat',
},
},
}
```

### Setting the active menu item

The active menu item receives a unique style treatment to indicate where the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import ifNonEmpty from '../../../internal/vendor/@carbon/web-components/globals/
import textNullable from '../../../../.storybook/knob-text-nullable';
import c4dLeftNav from '../left-nav';
import '../masthead-container';
import { CTA_TYPE } from '../../cta/defs';
import { L1_CTA_TYPES } from '../defs';
import styles from './masthead.stories.scss?lit';
import { ifDefined } from 'lit/directives/if-defined.js';
import { mastheadLinksV2 as links, mastheadL1Data, logoData } from './links';
Expand Down Expand Up @@ -86,6 +86,11 @@ async function customTypeaheadApiFunction(searchVal) {
});
}

const enumToArray = (en) =>
Object.keys(en)
.filter((value) => typeof value === 'string')
.map((key) => en[key]);

export const Default = (args) => {
const {
customProfileLogin,
Expand Down Expand Up @@ -342,13 +347,13 @@ withPlatform.story = {
};

export const withL1 = (args) => {
const { selectedMenuItem, selectedMenuItemL1, showContactCta, useMock } =
const { selectedMenuItem, selectedMenuItemL1, l1CtaType, useMock } =
args?.MastheadComposite ?? {};

let l1Data = { ...mastheadL1Data };
if (l1Data?.actions?.cta) {
showContactCta
? (l1Data.actions.cta.ctaType = CTA_TYPE.CHAT)
l1CtaType
? (l1Data.actions.cta.ctaType = l1CtaType)
: delete l1Data.actions.cta.ctaType;
}

Expand Down Expand Up @@ -397,7 +402,11 @@ withL1.story = {
'selected menu item in L1 (selected-menu-item-l1)',
''
),
showContactCta: boolean('use Contact module CTA', false),
l1CtaType: select(
'L1 CTA type',
enumToArray(L1_CTA_TYPES),
L1_CTA_TYPES.NONE
),
useMock: boolean('use mock nav data (use-mock)', false),
}),
},
Expand All @@ -406,7 +415,7 @@ withL1.story = {
MastheadComposite: {
selectedMenuItem: 'Consulting',
selectedMenuItemL1: '',
showContactCta: false,
l1CtaType: L1_CTA_TYPES.NONE,
useMock: false,
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('cds-masthead-composite', function () {
'c4d-masthead-composite'
);
expect(
mastheadComposite?.shadowRoot?.querySelector('c4d-masthead-global-bar')
mastheadComposite?.querySelector('c4d-masthead-global-bar')
).toMatchSnapshot();
});

Expand All @@ -51,7 +51,7 @@ describe('cds-masthead-composite', function () {
'c4d-masthead-composite'
);
expect(
mastheadComposite?.shadowRoot?.querySelector('c4d-masthead-global-bar')
mastheadComposite?.querySelector('c4d-masthead-global-bar')
).toMatchSnapshot();
});
});
Expand Down
16 changes: 16 additions & 0 deletions packages/web-components/src/components/masthead/defs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,19 @@ export enum MEGAMENU_LAYOUT_SCHEME {
TAB = 'tab',
LIST = 'list',
}

/**
* Matches CMaaS's CTA options.
*
* @see https://github.ibm.com/live-advisor/cm-app/blob/master/docs/cm-doc.md#calls-to-action
*/
export enum L1_CTA_TYPES {
NONE = '',
CONTACT_US = 'contact',
CHAT_NOW = 'chat',
EMAIL_US = 'email',
CALL_US = 'phone',
BOOK_A_CONSULTATION = 'scheduler',
REQUEST_A_DEMO = 'demo',
REQUEST_A_QUOTE = 'quote',
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import C4DMastheadL1 from './masthead-l1';
import './masthead';
import './masthead-button-cta';
import './masthead-l1';
import './masthead-l1-cta';
import './masthead-l1-name';
import './masthead-menu-button';
import './masthead-contact';
Expand Down Expand Up @@ -121,15 +122,18 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) {
* @returns {TemplateResult | undefined} The L1 nav.
*/
protected _renderL1() {
if (!this.l1Data) return undefined;

return html`
<c4d-masthead-l1
slot="masthead-l1"
.l1Data=${this.l1Data}
selected-menu-item=${this.selectedMenuItemL1 || ''}>
</c4d-masthead-l1>
`;
const { l1Data, selectedMenuItemL1 } = this;
const { cta } = l1Data?.actions || {};
return !l1Data
? undefined
: html`
<c4d-masthead-l1
slot="masthead-l1"
.l1Data=${l1Data}
selected-menu-item=${selectedMenuItemL1 || ''}>
${cta ? C4DMastheadL1.renderL1Cta(cta) : ''}
</c4d-masthead-l1>
`;
}

/**
Expand Down Expand Up @@ -1600,11 +1604,9 @@ class C4DMastheadComposite extends HostListenerMixin(LitElement) {
`;
}

// @TODO: check if needed after merge
static shadowRootOptions = {
...LitElement.shadowRootOptions,
delegatesFocus: true,
};
protected createRenderRoot() {
return this;
}

static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader
}
Expand Down
Loading

0 comments on commit 2f8fccf

Please sign in to comment.