diff --git a/.github/workflows/automerge-mastheadv2.yml b/.github/workflows/automerge-mastheadv2.yml deleted file mode 100644 index 5db50dfa20a..00000000000 --- a/.github/workflows/automerge-mastheadv2.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: automerge-mastheadv2 -on: - push: - branches: - - 'main' - -concurrency: - group: automerge-mastheadv2-${{ github.ref }} - cancel-in-progress: true - -jobs: - automerge-mastheadv2: - if: github.repository == 'carbon-design-system/carbon-for-ibm-dotcom' - runs-on: ubuntu-20.04 - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - steps: - - uses: actions/checkout@v4 - - name: Merge to feat/masthead-v2-dev - uses: devmasx/merge-branch@1.4.0 - with: - type: now - target_branch: 'feat/masthead-v2-dev' - env: - GITHUB_TOKEN: ${{secrets.MERGE_ACTION}} - - uses: act10ns/slack@v2 - with: - status: ${{ job.status }} - if: failure() diff --git a/.github/workflows/e2e-integration.yml b/.github/workflows/e2e-integration.yml index 3d0b951c377..4d715d291e6 100644 --- a/.github/workflows/e2e-integration.yml +++ b/.github/workflows/e2e-integration.yml @@ -2,7 +2,7 @@ name: e2e-integration on: push: - branches: [ main, release/v2*, feat/masthead-v2, feat/masthead-v2-dev ] + branches: [ main, release/v2* ] schedule: - cron: '0 20 * * 1-5' diff --git a/packages/styles/scss/components/card-group/_card-group.scss b/packages/styles/scss/components/card-group/_card-group.scss index 07b5e161088..4097a15cfad 100644 --- a/packages/styles/scss/components/card-group/_card-group.scss +++ b/packages/styles/scss/components/card-group/_card-group.scss @@ -77,11 +77,18 @@ &::after { content: revert; } + + &::after { + display: block; + aspect-ratio: 16 / 9; + content: ''; + grid-area: 1 / 1 / -1 / -1; + } } .#{$prefix}--card__content { display: grid; - grid-row: span 10; + grid-area: 1 / 1 / -1 / -1; grid-template-rows: subgrid; row-gap: 0; } diff --git a/packages/styles/scss/components/card/_card.scss b/packages/styles/scss/components/card/_card.scss index 5a83ccbd2a3..0f0cafc7eca 100644 --- a/packages/styles/scss/components/card/_card.scss +++ b/packages/styles/scss/components/card/_card.scss @@ -281,12 +281,6 @@ flex-direction: column; gap: $spacing-05; } - - ::slotted(div) { - /* stylelint-disable declaration-no-important */ - // need the !important to prevent CSS reset styles from overwritting margin for tags - margin-inline-start: -$spacing-02 !important; - } } :host(#{$c4d-prefix}-card[aspect-ratio='1:1']) .#{$prefix}--card__wrapper { diff --git a/packages/styles/scss/components/feature-card/_feature-card.scss b/packages/styles/scss/components/feature-card/_feature-card.scss index fc9e93262bb..7862c995bda 100644 --- a/packages/styles/scss/components/feature-card/_feature-card.scss +++ b/packages/styles/scss/components/feature-card/_feature-card.scss @@ -86,6 +86,10 @@ $feature-flags: ( flex: 1 0 50%; } + .#{$prefix}--card__image-wrapper { + aspect-ratio: 1 / 1; + } + .#{$prefix}--card__wrapper { &::before, &::after { @@ -247,10 +251,27 @@ $feature-flags: ( } } - :host(#{$c4d-prefix}-feature-card-footer)[color-scheme='inverse'] - .#{$c4d-prefix}-ce--card__footer - ::slotted(svg[slot='icon']) { - fill: $link-inverse; + :host(#{$c4d-prefix}-feature-card-footer)[color-scheme='inverse'] { + .#{$c4d-prefix}-ce--card__footer { + .#{$c4d-prefix}-ce--cta__icon, + ::slotted(svg[slot='icon']) { + fill: $link-inverse; + } + + &:hover { + .#{$c4d-prefix}-ce--cta__icon, + ::slotted(svg[slot='icon']) { + fill: $link-inverse-hover; + } + } + + &:active { + .#{$c4d-prefix}-ce--cta__icon, + ::slotted(svg[slot='icon']) { + fill: $link-inverse-active; + } + } + } } :host(#{$c4d-prefix}-feature-card[size='large']) { diff --git a/packages/styles/scss/components/leadspace/_leadspace.scss b/packages/styles/scss/components/leadspace/_leadspace.scss index ada884f65d1..61f4c7b02ae 100644 --- a/packages/styles/scss/components/leadspace/_leadspace.scss +++ b/packages/styles/scss/components/leadspace/_leadspace.scss @@ -464,6 +464,7 @@ $btn-min-width: 26; :host(#{$c4d-prefix}-leadspace) ::slotted([slot='navigation']) { z-index: 1; + max-inline-size: 40rem; // need the !important to prevent CSS reset styles from overwritting margin for tags /* stylelint-disable declaration-no-important */ padding-block-end: $spacing-05 !important; diff --git a/packages/styles/scss/components/notice-choice/_notice-choice.scss b/packages/styles/scss/components/notice-choice/_notice-choice.scss index 5a80d29e5ae..9a2cad8820b 100644 --- a/packages/styles/scss/components/notice-choice/_notice-choice.scss +++ b/packages/styles/scss/components/notice-choice/_notice-choice.scss @@ -9,6 +9,9 @@ @use '@carbon/styles/scss/spacing' as *; @use '@carbon/styles/scss/theme' as *; @use '@carbon/styles/scss/utilities/convert'; +@use '@carbon/type'; + +@include type.reset(); @mixin notice-choice { .#{$prefix}--nc { @@ -17,6 +20,7 @@ p, .#{$prefix}--checkbox-group { margin-block-end: $spacing-06; + @include type.type-style('legal-02'); } a { diff --git a/packages/styles/scss/components/tableofcontents/_table-of-contents.scss b/packages/styles/scss/components/tableofcontents/_table-of-contents.scss index a212ac2ac2c..b3ee02bd4a8 100644 --- a/packages/styles/scss/components/tableofcontents/_table-of-contents.scss +++ b/packages/styles/scss/components/tableofcontents/_table-of-contents.scss @@ -112,7 +112,6 @@ $hover-transition-timing: 95ms; @extend .#{$prefix}--col-lg-12; box-sizing: border-box; - padding-block: $spacing-05 $spacing-09; } .#{$prefix}--tableofcontents { diff --git a/packages/styles/scss/internal/content-block/_content-block.scss b/packages/styles/scss/internal/content-block/_content-block.scss index 0bc91c9e8f7..c2071965851 100644 --- a/packages/styles/scss/internal/content-block/_content-block.scss +++ b/packages/styles/scss/internal/content-block/_content-block.scss @@ -86,6 +86,7 @@ } ::slotted(#{$c4d-prefix}-content-group:not([slot])), + ::slotted(#{$c4d-prefix}-cta-block-item-row:not([slot])), ::slotted([data-autoid^='c4d--tabs-']:not([slot])), ::slotted([data-autoid^='c4d--card']:not([slot])) { margin-inline-start: 0; diff --git a/packages/web-components/.storybook/container.scss b/packages/web-components/.storybook/container.scss index e36c24b5abf..a6eafe14351 100644 --- a/packages/web-components/.storybook/container.scss +++ b/packages/web-components/.storybook/container.scss @@ -1,7 +1,7 @@ // // @license // -// Copyright IBM Corp. 2020, 2021 +// 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. @@ -25,28 +25,28 @@ @include grid.flex-grid(); :root { - @include theme($white, true); + @include theme($white); - height: 100%; + block-size: 100%; } :root[storybook-carbon-theme='g10'] { - @include theme($g10, true); + @include theme($g10); } :root[storybook-carbon-theme='g90'] { - @include theme($g90, true); + @include theme($g90); } :root[storybook-carbon-theme='g100'] { - @include theme($g100, true); + @include theme($g100); } body { // `@include css-body` has `font-family: inherit` via `@include type-style('body-short-01')`, // which kills `font-family` from `@include carbon--type-reset` - color: $text-primary; background-color: $background; + color: $text-primary; line-height: 1; } @@ -71,6 +71,5 @@ html { } .c4d-story-padding { - padding-top: $spacing-05; - padding-bottom: $spacing-05; + padding-block: $spacing-05; } diff --git a/packages/web-components/src/components/button/button.ts b/packages/web-components/src/components/button/button.ts index a89e4300bb1..f0fc96070f7 100644 --- a/packages/web-components/src/components/button/button.ts +++ b/packages/web-components/src/components/button/button.ts @@ -7,16 +7,16 @@ * LICENSE file in the root directory of this source tree. */ -import { LitElement, html } from 'lit'; +import { html, LitElement } from 'lit'; import { property, query } from 'lit/decorators.js'; import settings from '@carbon/ibmdotcom-utilities/es/utilities/settings/settings.js'; import styles from './button.scss'; import StableSelectorMixin from '../../globals/mixins/stable-selector'; import { carbonElement as customElement } from '@carbon/web-components/es/globals/decorators/carbon-element.js'; -import CTAMixin from '../../component-mixins/cta/cta'; +import CTAMixin, { ariaLabels, icons } from '../../component-mixins/cta/cta'; import CDSButton from '@carbon/web-components/es/components/button/button.js'; +import { CTA_TYPE } from '../cta/defs'; -import { ariaLabels, icons } from '../../component-mixins/cta/cta'; const { prefix, stablePrefix: c4dPrefix } = settings; /** @@ -89,7 +89,11 @@ class C4DButton extends CTAMixin(StableSelectorMixin(CDSButton)) { */ // @ts-ignore: The decorator refers to this method but TS thinks this method is not referred to private _handleVideoTitleUpdate = async (event) => { - if (event) { + if ( + event && + this.ctaType === CTA_TYPE.VIDEO && + this.href === event.detail?.videoId + ) { const { videoDuration, videoName } = event.detail as any; const { formatVideoDuration, formatVideoCaption } = this; const formattedVideoDuration = formatVideoDuration({ diff --git a/packages/web-components/src/components/card/card.ts b/packages/web-components/src/components/card/card.ts index f1c14c7d56a..2a1f42a695e 100644 --- a/packages/web-components/src/components/card/card.ts +++ b/packages/web-components/src/components/card/card.ts @@ -340,7 +340,9 @@ class C4DCard extends CTAMixin(StableSelectorMixin(CDSLink)) { formatVideoCaption: formatVideoCaptionInEffect, formatVideoDuration: formatVideoDurationInEffect, } = this; - const footer = this.querySelector(`${c4dPrefix}-card-footer`); + const footer = this.querySelector( + (this.constructor as typeof C4DCard).selectorFooter + ); const headingText = this.querySelector( `${c4dPrefix}-card-heading` diff --git a/packages/web-components/src/components/feature-card/__stories__/feature-card.stories.ts b/packages/web-components/src/components/feature-card/__stories__/feature-card.stories.ts index be5d9aebde6..46771634acd 100644 --- a/packages/web-components/src/components/feature-card/__stories__/feature-card.stories.ts +++ b/packages/web-components/src/components/feature-card/__stories__/feature-card.stories.ts @@ -21,11 +21,13 @@ import imgLg1x1 from '../../../../.storybook/storybook-images/assets/720/fpo--1x import imgXlg1x1 from '../../../../.storybook/storybook-images/assets/1312/fpo--1x1--1312x1312--002.jpg'; import imgMax1x1 from '../../../../.storybook/storybook-images/assets/1584/fpo--1x1--1584x1584--002.jpg'; import settings from '@carbon/ibmdotcom-utilities/es/utilities/settings/settings.js'; +import { typeOptions, types } from '../../cta/__stories__/ctaTypeConfig'; const { stablePrefix: c4dPrefix, prefix } = settings; import readme from './README.stories.mdx'; import textNullable from '../../../../.storybook/knob-text-nullable'; +import { CTA_TYPE } from '../../cta/defs'; const colorSchemeMap = { Regular: BASIC_COLOR_SCHEME.REGULAR, @@ -33,41 +35,35 @@ const colorSchemeMap = { }; export const Medium = (args) => { - const { heading, href, colorScheme } = + const { heading, href, colorScheme, ctaType } = args?.[`${c4dPrefix}-feature-card`] ?? {}; return html` - - - - - - - - - - - - - - ${heading} - - + + + + + + + + + + + + + + + ${heading} + + + `; }; -Medium.story = { - parameters: { - percy: { - skip: true, - }, - }, -}; - export const Large = (args) => { - const { eyebrow, heading, copy, href, colorScheme } = + const { eyebrow, heading, copy, href, colorScheme, ctaType } = args?.[`${c4dPrefix}-feature-card`] ?? {}; const copyComponent = document @@ -77,36 +73,35 @@ export const Large = (args) => { copyComponent!.innerHTML = copy; } return html` - - - - - - - - - - - - - - ${eyebrow} - ${heading} - ${copy && html`

`} - -
+ + + + + + + + + + + + + + + ${eyebrow} + ${heading} + ${copy ? html`

${copy}

` : ''} + +
+
`; }; Large.story = { parameters: { - percy: { - skip: true, - }, storyGrid: `${prefix}--col-lg-12`, knobs: { [`${c4dPrefix}-feature-card`]: () => ({ @@ -124,6 +119,11 @@ Large.story = { ), href: textNullable('Card Href (href):', 'https://example.com'), colorScheme: select('Color scheme:', ['Regular', 'Inverse'], 'Regular'), + ctaType: select( + 'CTA type (cta-type)', + typeOptions, + types[CTA_TYPE.LOCAL] + ), }), }, propsSet: { @@ -164,6 +164,11 @@ export default { ), href: textNullable('Card Href (href):', 'https://example.com'), colorScheme: select('Color scheme:', ['Regular', 'Inverse'], 'Regular'), + ctaType: select( + 'CTA type (cta-type)', + typeOptions, + types[CTA_TYPE.LOCAL] + ), }), }, propsSet: { 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 d2074f16cd0..46c3c2ff64b 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,8 @@ import '@carbon/ibmdotcom-web-components/es/components/notice-choice/index.js'; state="CA" terms-condition-link="" hide-error-message="false" - enable-all-opt-in=""> + combine-email-phone="false" + > ``` @@ -65,6 +66,8 @@ document.addEventListener('cds-notice-choice-change', (event) => { | language | form based on the country and language | en | | terms-condition-link | Terms and conditions link appended to the end of the privacy statement - should be specific | | | hide-error-message | Hide Error Messages for PUNS statement | false | +| combine-email-phone | Combine Email and Phone | false | +| environment | Set environment variable Prod or Stage | Prod | 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 98d8541e375..c391880c2d1 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 @@ -44,7 +44,7 @@ const languages = { 'Ukrainian [uk]': 'uk', }; const countryList = { - 'Unites States': 'US', + 'United States': 'US', Germany: 'DE', India: 'IN', China: 'CN', @@ -87,6 +87,16 @@ const hideErrorMessages = { true: 'true', false: 'false', }; + +const combineEmailPhone = { + true: 'true', + false: 'false', +}; + +const environment = { + Production: 'prod', + Stage: 'stage', +}; const onChange = (event: CustomEvent) => { console.log(event.detail); }; @@ -109,11 +119,15 @@ const props = () => { hideErrorMessages, 'false' ), + combineEmailPhone: select( + 'Combine Email Phone', + combineEmailPhone, + 'false' + ), + environment: select('Environment', environment, 'prod'), }; }; -console.log(props); - export const Default = (args) => { const { language, @@ -127,6 +141,8 @@ export const Default = (args) => { hiddenPhone, ncTeleDetail, ncEmailDetail, + combineEmailPhone, + environment, } = args?.NoticeChoice ?? {}; return html` { .hiddenPhone="${hiddenPhone}" .nc-tele-detail="${ncTeleDetail}" .nc-email-detail="${ncEmailDetail}" + combine-email-phone="${combineEmailPhone}" + environment="${environment}" @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 e0f1ad1b51a..95aa58e32b4 100644 --- a/packages/web-components/src/components/notice-choice/notice-choice.ts +++ b/packages/web-components/src/components/notice-choice/notice-choice.ts @@ -56,6 +56,9 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { @property({ type: String, attribute: 'language' }) language = 'en'; + @property({ type: String, attribute: 'currentLanguage' }) + currentLanguage = 'en'; + @property({ type: String, attribute: 'terms-condition-link' }) termsConditionLink = html``; @@ -68,6 +71,12 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { @property({ type: Boolean, attribute: 'hide-error-message' }) hideErrorMessage = false; + @property({ type: Boolean, attribute: 'combine-email-phone' }) + combineEmailPhone = false; + + @property({ type: String, attribute: 'environment' }) + environment = 'prod'; + @property({ type: Object, attribute: false }) checkboxes = {}; @@ -98,6 +107,9 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { @property({ type: Boolean, attribute: false }) telephonePrechecked = false; + @property({ type: Boolean, attribute: false }) + combinedEmailPhonePrechecked = false; + /** * End properties for passed attributes. */ @@ -144,6 +156,7 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { defaultLoadContent() { loadContent( 'en', + this.environment, (ncData) => { this.ncData = ncData; this.prepareCheckboxes(); @@ -174,6 +187,7 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { } else if (supportedLanguages(language)) { defaultLanguage = supportedLanguages(language); } + loadSettings( (countryPreferencesSettings) => { this.countrySettings = countryPreferencesSettings; @@ -184,6 +198,7 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { ); loadContent( defaultLanguage, + this.environment, (ncData) => { this.ncData = ncData; this.prepareCheckboxes(); @@ -211,7 +226,17 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { const hiddenFieldName = `NC_HIDDEN_${key}`; newValues[hiddenFieldName] = option[hiddenFieldName]; - this._onChange(hiddenFieldName, newValues[key] ? 'OPT_IN' : 'OPT_OUT'); + if (this.combineEmailPhone) { + this._onChange( + hiddenFieldName, + newValues.EMAIL ? 'OPT_IN' : 'OPT_OUT' + ); + } else { + this._onChange( + hiddenFieldName, + newValues[key] ? 'OPT_IN' : 'OPT_OUT' + ); + } }); if (JSON.stringify(this.values) !== JSON.stringify(newValues)) { this.values = newValues; @@ -250,6 +275,7 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { * @description * change checkbox checked option based on new country. */ + this.setDefaultSelections(); } } @@ -266,6 +292,7 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { attributeChangedCallback(name, oldVal, newVal) { const hasValue = newVal !== null && oldVal !== null; super.attributeChangedCallback(name, oldVal, newVal); + switch (name) { case 'question-choices': { // Reload checkbox options when questionchoices changed @@ -275,7 +302,8 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { } break; } - case 'language': { + case 'language': + case 'environment': { // load content when locale changed. const [language] = newVal.split(/[-_]/); @@ -285,10 +313,11 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { } else if (supportedLanguages(language)) { defaultLanguage = supportedLanguages(language); } - + this.currentLanguage = defaultLanguage; if (hasValue && oldVal !== newVal) { loadContent( defaultLanguage, + this.environment, (ncData) => { this.ncData = ncData; this.prepareCheckboxes(); @@ -327,6 +356,12 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { break; } + case 'combine-email-phone': { + if (oldVal !== newVal) { + this.combineEmailPhone = JSON.parse(newVal); + } + break; + } } } @@ -565,6 +600,183 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { return html``; } } + + combinedPreTextTemplate() { + if (!this.ncData) { + return html``; + } + + const ecmTranslateContent = this.ncData; + const country = this.country?.toLocaleLowerCase() || ''; + const state = this.state?.toLocaleLowerCase() || ''; + let preText = ecmTranslateContent.combinedConsent; + + if (ecmTranslateContent.state[country]) { + if (country === 'us') { + preText = + state === 'ca' || state === '' + ? ecmTranslateContent.state[country]['ca'].noticeOnly + : ecmTranslateContent.noticeOnly; + } else { + preText = + ecmTranslateContent.state[country][state]?.combinedConsent || + ecmTranslateContent.combinedConsent; + } + } else if (country === 'us') { + preText = + state === 'ca' || state === '' || typeof state === 'undefined' + ? ecmTranslateContent.state?.[country]?.['ca']?.noticeOnly + ? ecmTranslateContent.state?.[country]?.['ca']?.noticeOnly + : ecmTranslateContent.noticeOnly + : ecmTranslateContent.noticeOnly; + } + + if (ecmTranslateContent.country?.[country]) { + preText = ecmTranslateContent.country[country].combinedConsent; + } + + if (country !== 'us') { + const checked = this.values.EMAIL; + preText = preText + ? this.renderCheckbox(preText, checked) + : this.renderCheckbox(ecmTranslateContent.preText, checked); + return preText; + } + + return html`${unsafeHTML(preText)}`; + } + + checkCombineEmailPhoneBoxChange($event: any) { + const checked = $event.target.checked; + const newValues = { + ...this.values, + }; + this.changed = true; + + Object.keys(this.checkboxes).map((id) => { + newValues[id] = !!checked; + this.values = newValues; + console.log(this.combinedEmailPhonePrechecked); + const hiddenFieldName = `NC_HIDDEN_${id}`; + const hiddenFieldStatus = checked ? 'PERMISSION' : 'SUPPRESSION'; + this.values[id] = {}; + this.values[id]['checkBoxStatus'] = hiddenFieldStatus; + let statusPrechecked = ''; + switch (id) { + case 'EMAIL': + case 'PHONE': + statusPrechecked = + this.combinedEmailPhonePrechecked && !checked + ? 'CU' + : !this.combinedEmailPhonePrechecked && checked + ? 'UC' + : this.combinedEmailPhonePrechecked && checked + ? 'CC' + : 'UU'; + + break; + } + this.values[id]['punsStatus'] = statusPrechecked; + + this._onChange(hiddenFieldName, hiddenFieldStatus); + this._onChange( + `${hiddenFieldName}_VALUE`, + `NC_HIDDEN_${hiddenFieldStatus}` + ); + }); + } + renderCheckbox(preText, checked) { + const checkboxId = 'EMAIL_PHONE_CHECKBOX'; + return html` + +
+ + +
+
+ `; + } + + renderCombinedEmailPhoneSection() { + const getPunsStatus = (key, checked) => + this.country?.toLocaleLowerCase() === 'us' + ? 'NOTICE_ONLY' + : this.values[key]?.punsStatus || (checked ? 'CC' : 'UU'); + + const createHiddenInput = (id, value) => + html``; + + return html` +
+

+ ${this.countryBasedLegalNotice()} ${this.combinedPreTextTemplate()} +

+ ${Object.keys(this.checkboxes).map((key) => { + const checked = this.values.EMAIL; + const punsStatus = getPunsStatus(key, checked); + const hiddenBox = { + id: `NC_HIDDEN_${key}`, + value: this.values[key]['checkBoxStatus'] + ? this.values[key]['checkBoxStatus'] + : this.values.EMAIL + ? 'PERMISSION' + : 'SUPPRESSION', + }; + if (typeof checked !== 'object') { + this.combinedEmailPhonePrechecked = checked ? true : false; + } + + this._onChange( + `NC_${key === 'PHONE' ? 'TELE' : key}_DETAIL`, + `${key}_${punsStatus}` + ); + console.log(`${hiddenBox.id}_VALUE`, `NC_HIDDEN_${hiddenBox.value}`); + this._onChange( + `${hiddenBox.id}_VALUE`, + `NC_HIDDEN_${hiddenBox.value}` + ); + + if (Object.keys(this.checkboxes).length === 1) { + this._onChange(`NC_HIDDEN_PHONE_VALUE`, `NC_HIDDEN_PHONE_NONE`); + } + + return createHiddenInput(hiddenBox.id, hiddenBox.value); + })} +
+ ${this.postTextTemplate()} +
+ ${createHiddenInput( + 'preventFormSubmission', + this.preventFormSubmission + )} + +
+ `; + } + render() { if ( this.isMandatoryCheckboxDisplayed.isDisplayed && @@ -582,6 +794,11 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { ].chinaPIPLtext.mrs_field; this._onChange(mrsField, 'countyBasedCheckedNo'); } + + if (this.combineEmailPhone) { + return this.renderCombinedEmailPhoneSection(); + } + return html`

${this.countryBasedLegalNotice()} ${this.preTextTemplate()}

@@ -724,12 +941,14 @@ class NoticeChoice extends StableSelectorMixin(LitElement) { PHONE_CC: 'PHONE_CC', PHONE_UC: 'PHONE_UC', PHONE_UU: 'PHONE_UU', + EMAIL_NOTICE_ONLY: 'EMAIL_NOTICE_ONLY', + PHONE_NOTICE_ONLY: 'PHONE_NOTICE_ONLY', + NC_HIDDEN_PHONE_NONE: 'NC_HIDDEN_PHONE_NONE', }; if (Object.prototype.hasOwnProperty.call(pwsFieldsMap, field)) { field = pwsFieldsMap[field]; } - const init = { bubbles: true, detail: { diff --git a/packages/web-components/src/components/notice-choice/services.ts b/packages/web-components/src/components/notice-choice/services.ts index 96a3a957b8a..c2514492983 100644 --- a/packages/web-components/src/components/notice-choice/services.ts +++ b/packages/web-components/src/components/notice-choice/services.ts @@ -5,11 +5,17 @@ * LICENSE file in the root directory of this source tree. */ -export function loadContent(locale: string, onSuccess: any, onError: any) { +export function loadContent( + locale: string, + env: string, + onSuccess: any, + onError: any +) { const script = document.createElement('script'); + const environment = env === 'prod' ? '1.www.s81c.com' : '1.wwwstage.s81c.com'; script.async = false; script.charset = 'utf-8'; - script.src = `https://www.ibm.com/common/translations/notice/v23/${locale.toLocaleLowerCase()}/ncContent_v23.js`; // URL for the third-party library being loaded. + script.src = `https://${environment}/common/translations/notice/v23/${locale.toLocaleLowerCase()}/ncContent_v23.js`; // URL for the third-party library being loaded. document.body.appendChild(script); script.onload = () => { try { diff --git a/packages/web-components/src/components/notice-choice/utils.ts b/packages/web-components/src/components/notice-choice/utils.ts index b29e554ee8c..ad7e65ac585 100644 --- a/packages/web-components/src/components/notice-choice/utils.ts +++ b/packages/web-components/src/components/notice-choice/utils.ts @@ -49,6 +49,9 @@ export function pwsValueMap(value) { PHONE_CC: 'CC', PHONE_UC: 'UC', PHONE_UU: 'UU', + EMAIL_NOTICE_ONLY: 'NOTICE_ONLY', + PHONE_NOTICE_ONLY: 'NOTICE_ONLY', + NC_HIDDEN_PHONE_NONE: 'N', }[value] || null ); } diff --git a/packages/web-components/src/components/table-of-contents/__stories__/table-of-contents.stories.scss b/packages/web-components/src/components/table-of-contents/__stories__/table-of-contents.stories.scss index 356781345dc..3d254ff34f0 100644 --- a/packages/web-components/src/components/table-of-contents/__stories__/table-of-contents.stories.scss +++ b/packages/web-components/src/components/table-of-contents/__stories__/table-of-contents.stories.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. @@ -9,7 +9,7 @@ @use '@carbon/ibmdotcom-styles/scss/globals/vars' as *; .#{$c4d-prefix}-ce-demo--table-of-contents { - padding: 0 $spacing-05; + padding: $spacing-05; h3 { padding-block: $spacing-07; diff --git a/packages/web-components/tests/e2e-storybook/cypress/integration/button-group/button-group.e2e.js b/packages/web-components/tests/e2e-storybook/cypress/integration/button-group/button-group.e2e.js new file mode 100644 index 00000000000..5a71e024cf2 --- /dev/null +++ b/packages/web-components/tests/e2e-storybook/cypress/integration/button-group/button-group.e2e.js @@ -0,0 +1,79 @@ +/** + * Copyright IBM Corp. 2021, 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. + */ + +/** + * Sets the correct defaultPath for Button Group + * + * @type {string} + * @private + */ +const _defaultPath = '/iframe.html?id=components-button-group--default'; + +/* eslint-disable cypress/no-unnecessary-waiting */ +describe('c4d-button-group | default', () => { + beforeEach(() => { + cy.visit(`/${_defaultPath}`); + cy.injectAxe(); + cy.viewport(1280, 780); + }); + + it('should check a11y', () => { + cy.checkAxeA11y(); + }); + + it('should use given labels', () => { + cy.visit( + `/${_defaultPath}&knob-Button%201=Test%20Me%20Once&knob-Button%202=Test%20Me%20Twice` + ); + cy.get('c4d-button-group-item') + .first() + .should('have.text', 'Test Me Once') + .next() + .should('have.text', 'Test Me Twice'); + + cy.takeSnapshots(); + }); + + it('should use given labels with video cta-type mixed in', () => { + cy.visit( + `/${_defaultPath}&knob-Button%201=Test%20Me%20Once&knob-Button%202=Test%20Me%20Twice&knob-CTA%20type%20(cta-type)%202=video` + ); + cy.get('c4d-button-group-item') + .first() + .should('have.text', 'Test Me Once') + .next() + .should('have.text', 'Test Me Twice'); + + cy.takeSnapshots(); + }); + + it('should use video name for a video cta-type that has no label', () => { + cy.visit( + `/${_defaultPath}&knob-Button%201=Test%20Me%20Once&knob-Button%202=%20&knob-CTA%20type%20(cta-type)%202=video` + ); + cy.get('c4d-button-group-item') + .first() + .should('have.text', 'Test Me Once') + .next() + .should('not.be.empty'); + + cy.takeSnapshots(); + }); + + it('should not use video name for buttons that are not cta-type video', () => { + cy.visit( + `/${_defaultPath}&knob-Button%201=%20&knob-Button%202=%20&knob-CTA%20type%20(cta-type)%202=video` + ); + cy.get('c4d-button-group-item') + .first() + .should('contain.text', '') + .next() + .should('not.be.empty'); + + cy.takeSnapshots(); + }); +}); diff --git a/packages/web-components/tests/e2e-storybook/cypress/integration/feature-card/feature-card.e2e.js b/packages/web-components/tests/e2e-storybook/cypress/integration/feature-card/feature-card.e2e.js index efe89a4b5c8..fdd56450121 100644 --- a/packages/web-components/tests/e2e-storybook/cypress/integration/feature-card/feature-card.e2e.js +++ b/packages/web-components/tests/e2e-storybook/cypress/integration/feature-card/feature-card.e2e.js @@ -62,10 +62,10 @@ describe('c4d-feature-card | medium', () => { }); }); - it.skip('should have image on the left and content on the right side of the card', () => { + it('should have image on the left and content on the right side of the card', () => { // image takes the left half cy.get('c4d-image').then(($image) => { - expect($image[0].getBoundingClientRect().left).to.equal(32); + expect($image[0].getBoundingClientRect().left).to.equal(33); expect($image[0].getBoundingClientRect().right).to.equal(328); }); @@ -75,7 +75,7 @@ describe('c4d-feature-card | medium', () => { .find('.cds--card__wrapper') .then(($content) => { expect($content[0].getBoundingClientRect().left).to.equal(328); - expect($content[0].getBoundingClientRect().right).to.equal(624); + expect($content[0].getBoundingClientRect().right).to.equal(623); }); }); @@ -161,16 +161,17 @@ describe('c4d-feature-card | large', () => { }); }); - it.skip('should have eyebrow, heading, and copy content', () => { + it('should have eyebrow, heading, and copy content', () => { cy.get('c4d-card-eyebrow').invoke('text').should('not.be.empty'); cy.get('c4d-card-heading').invoke('text').should('not.be.empty'); cy.get('c4d-feature-card > p').invoke('text').should('not.be.empty'); }); + - it.skip('should have image on the left and content on the right half of the card', () => { + it('should have image on the left and content on the right half of the card', () => { // image takes the left half cy.get('c4d-image').then(($image) => { - expect($image[0].getBoundingClientRect().left).to.equal(16); + expect($image[0].getBoundingClientRect().left).to.equal(33); expect($image[0].getBoundingClientRect().right).to.equal(529); }); @@ -180,7 +181,7 @@ describe('c4d-feature-card | large', () => { .find('.cds--card__wrapper') .then(($content) => { expect($content[0].getBoundingClientRect().left).to.equal(529); - expect($content[0].getBoundingClientRect().right).to.equal(1042); + expect($content[0].getBoundingClientRect().right).to.equal(1025); }); });