Skip to content

Commit

Permalink
feat(promo-banner): add components (#12100)
Browse files Browse the repository at this point in the history
### Related Ticket(s)

[ADCMS-6656](https://jsw.ibm.com/browse/ADCMS-6656)

### Description

Migrates the `promo-banner` component from carbon-for-aem into carbon-for-ibmdotcom

### Changelog

**New**

- Added the `c4d-promo-banner` component.
  • Loading branch information
Valentin-Sorin-Nicolae authored Nov 13, 2024
1 parent f49c073 commit 417143c
Show file tree
Hide file tree
Showing 5 changed files with 478 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Meta, Props, Story, Canvas, Description } from '@storybook/addon-docs';
import { cdnJs } from '../../../globals/internal/storybook-cdn';
import '../index.ts';

<Meta title="Promo Banner" />

# Promo Banner

<Canvas withToolbar>
<Story id="components-promo-banner--default" height="100px" />
</Canvas>

<Description markdown={`${cdnJs({ components: ['promo-banner'] })}`} />

### `<c4d-promo-banner>` attributes, properties, and events

<Props of="c4d-promo-banner" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/**
* @license
*
* Copyright IBM Corp. 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 { boolean, select, text } from '@storybook/addon-knobs';
import { html } from 'lit';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import '../index';
import '../../cta/index';
import '../../image/index';
import '../../table-of-contents/index';
import { types } from '../../../component-mixins/cta/cta';

import readme from './README.stories.mdx';

const incompatibleTypes = ['video', 'email', 'schedule', 'chat', 'call'];
const ctaTypes = Object.values(types).filter(
(val) => !!val && !incompatibleTypes.includes(val)
);

export default {
title: 'Components/Promo Banner',
parameters: {
...readme.parameters,
knobs: {
escapeHTML: false,
PromoBanner: () => {
const heading = text(
'Heading (HTML Enabled)',
'<h5>Try a demo of Watson<span style="color:#0f62fe;">X</span></h5>'
);
const body = text(
'Body Text (HTML Enabled)',
'<p>Easily deploy and embed AI across your business.</p>'
);
const cta = text('CTA Label', 'Try Today');
const ctaType = select('CTA Type', ctaTypes, ctaTypes[0]);
const tocLayout = boolean('Render in TOC', false);
const hasImage = boolean('Has Image', true);
return {
heading,
body,
cta,
ctaType,
tocLayout,
hasImage,
};
},
},
},

decorators: [
(story, { args }) => {
return html`
<div class="c4d-story-padding">
${args?.PromoBanner?.tocLayout
? html`
<c4d-table-of-contents class="cds--grid">
<div class="cds--row">
<div class="cds--col cds--no-gutter">
<div name="TOC Label" data-title="Promotional Banner">
${story()}
</div>
</div>
</div>
</c4d-table-of-contents>
`
: html`
<div class="cds--grid">
<div class="cds--row">
<div class="cds--col cds--no-gutter">${story()}</div>
</div>
</div>
`}
</div>
`;
},
],
};

export const Default = (args) => {
const { heading, body, hasImage, cta, ctaType } = args?.PromoBanner ?? {};
return html`
<c4d-promo-banner>
${hasImage !== false // Need explicit check to test image container queries.
? html`
<c4d-image
alt="Image alt text"
slot="image"
width="300"
height="300"
default-src="https://fpoimg.com/300x300?&bg_color=5396ee&text_color=161616">
<c4d-image-item
media="(min-width:1584px)"
srcset="https://fpoimg.com/600x600?&bg_color=ee5396&text_color=161616"></c4d-image-item>
<c4d-image-item
media="(min-width:1312px)"
srcset="https://fpoimg.com/400x400?&bg_color=53ee96&text_color=161616"></c4d-image-item>
</c4d-image>
`
: ''}
${unsafeHTML(heading)} ${unsafeHTML(body)}
${cta
? html`
<c4d-button-cta
cta-type="${ctaType}"
kind="tertiary"
slot="cta"
href="https://example.com"
>${cta}</c4d-button-cta
>
`
: ''}
</c4d-promo-banner>
`;
};
10 changes: 10 additions & 0 deletions packages/web-components/src/components/promo-banner/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* @license
*
* Copyright IBM Corp. 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 './promo-banner';
163 changes: 163 additions & 0 deletions packages/web-components/src/components/promo-banner/promo-banner.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/**
* @license
*
* Copyright IBM Corp. 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.
*/

@use '@carbon/ibmdotcom-styles/scss/globals/vars' as *;
@use '@carbon/styles/scss/utilities';
@use '@carbon/styles/scss/spacing' as *;
@use '@carbon/styles/scss/theme' as *;
@use '@carbon/styles/scss/type' as *;
@use '@carbon/grid' as *;
@use '@carbon/ibmdotcom-styles/scss/globals/utils/flex-grid' as *;

$css--plex: true !default;
$half-gutter: $grid-gutter / 2;

$md-breakpoint-width: map-get(map-get($grid-breakpoints, md), width);
$lg-breakpoint-width: map-get(map-get($grid-breakpoints, lg), width);
$xlg-breakpoint-width: map-get(map-get($grid-breakpoints, xlg), width);
$max-breakpoint-width: map-get(map-get($grid-breakpoints, max), width);

// TODO: Move these calculations to a single importable file.
//
// We need lower and upper bounds for a container occupying 12 / 16 columns at
// the lg and xlg breakpoints. For the lower bound we take the breakpoint
// size, less the 2rem of outer padding, multiplied by 12 / 16, less 2rem of
// column padding. For the upper bound we take the next breakpoint size and
// do a similar calculation with a slight tweak of subtracting 0.02 from the
// breakpoint size as a starting point, similar to how the
// breakpoint-between mixin works. Note that this approach my not work
// cleanly for the narrow or condensed grid due to the necessary assumptions
// made for padding widths.
$lg-12-column-lower-bound: ($lg-breakpoint-width * (12 / 16)) - 2rem;
$lg-12-column-upper-bound: ($xlg-breakpoint-width - 0.02) * (12 / 16);
$xlg-12-column-lower-bound: $xlg-breakpoint-width * (12 / 16);
$xlg-12-column-upper-bound: ($max-breakpoint-width - 0.02) * (12 / 16);

:host(#{$c4d-prefix}-promo-banner) {
display: block;
/* stylelint-disable-next-line property-no-unknown */
container: promo-banner / inline-size;

[hidden] {
/* stylelint-disable-next-line declaration-no-important */
display: none !important;
}

.banner-wrapper {
position: relative;
display: flex;
flex-wrap: nowrap;
align-items: start;
background-color: $layer;
color: $text-primary;

@include breakpoint-down(lg) {
&:not(.no-cta) {
/* stylelint-disable-next-line c4d/require-color-with-bg */
&:hover {
background-color: $layer-hover;
}

&:focus-within {
outline: $spacing-01 solid $focus;
outline-offset: calc(-1 * #{$spacing-01});
}
}
}
}

.banner-image {
position: relative;
align-self: stretch;

@include make-col(4, 16);
@include breakpoint(lg) {
/* stylelint-disable-next-line scss/at-rule-no-unknown */
@container promo-banner (inline-size <= #{$lg-12-column-upper-bound}) {
display: none;
}
}

@include breakpoint(xlg) {
/* stylelint-disable-next-line scss/at-rule-no-unknown */
@container promo-banner (inline-size <= #{$xlg-12-column-upper-bound}) {
display: none;
}
}
}

::slotted([slot='image']) {
/* stylelint-disable-next-line property-no-unknown */
position: absolute;
aspect-ratio: auto;
block-size: 100%;
inline-size: 100%;
padding-block: 0;
}

.banner-content {
flex-grow: 1;
padding-block: $spacing-05;
padding-inline: $half-gutter;

@include breakpoint(md) {
padding-block: $spacing-07;
}
}

.banner-cta {
padding-block: $spacing-05;
padding-inline: $half-gutter;
text-align: end;

@include make-col(1, 4);

@include breakpoint-down(lg) {
&:focus {
outline: none;
}

&::after {
position: absolute;
display: block;
content: '';
inset: 0;
}
}

@include breakpoint(md) {
@include make-col(1, 8);

padding-block: $spacing-07;
}

@include breakpoint(lg) {
text-align: start;

@include make-col(4, 16);
@include make-col-offset(2, 16);

/* stylelint-disable-next-line scss/at-rule-no-unknown */
@container promo-banner (inline-size <= #{$lg-12-column-upper-bound}) {
@include make-col(4, 12);
}
}

@include breakpoint(xlg) {
/* stylelint-disable-next-line scss/at-rule-no-unknown */
@container promo-banner (inline-size <= #{$xlg-12-column-upper-bound}) {
@include make-col(4, 12);
}
}
}

::slotted([slot='cta']) {
inline-size: 100%;
}
}
Loading

0 comments on commit 417143c

Please sign in to comment.