diff --git a/.yarn/cache/@carbon-feature-flags-npm-0.15.0-4a32745220-211827fec1.zip b/.yarn/cache/@carbon-feature-flags-npm-0.15.0-4a32745220-211827fec1.zip new file mode 100644 index 00000000000..6145df82832 Binary files /dev/null and b/.yarn/cache/@carbon-feature-flags-npm-0.15.0-4a32745220-211827fec1.zip differ diff --git a/.yarn/cache/@carbon-icon-helpers-npm-10.43.1-5c55dbfa40-b77039f58d.zip b/.yarn/cache/@carbon-icon-helpers-npm-10.43.1-5c55dbfa40-b77039f58d.zip new file mode 100644 index 00000000000..2866a3b6bb0 Binary files /dev/null and b/.yarn/cache/@carbon-icon-helpers-npm-10.43.1-5c55dbfa40-b77039f58d.zip differ diff --git a/.yarn/cache/@carbon-motion-npm-11.15.0-1f597eb298-985a559324.zip b/.yarn/cache/@carbon-motion-npm-11.15.0-1f597eb298-985a559324.zip new file mode 100644 index 00000000000..ec8df628340 Binary files /dev/null and b/.yarn/cache/@carbon-motion-npm-11.15.0-1f597eb298-985a559324.zip differ diff --git a/docs/dotcom-v2-migration.md b/docs/dotcom-v2-migration.md index 76968d32609..a7d7702f849 100644 --- a/docs/dotcom-v2-migration.md +++ b/docs/dotcom-v2-migration.md @@ -33,6 +33,8 @@ For Carbon v11 migration guidance, see their | content-group-simple | This component is deprecated in v2 in favor for content-group, image, & content-item components | | cta-block | This component is deprecated in v2 in favor for content-section/block & content-item components | | cta-section | This component is deprecated in v2 in favor for content-section/block & content-item components | +| image | View changes [here](#image) | +| image-with-caption | Replaced by `image` | | link-list-section | This component is deprecated in v2 in favor for content-section/block & link-list end of section variant components | | logo-grid | This component is deprecated in v2 in favor for content-section/block & image-group components | | pictogram-item | This component is deprecated in v2 in favor for content-item (pictogram variation) componet | @@ -41,4 +43,8 @@ For Carbon v11 migration guidance, see their ### BackToTop -- \ No newline at end of file +- + +### Image + +- New `lightbox-contrast` property \ No newline at end of file diff --git a/packages/styles/scss/components/callout-with-media/_callout-with-media.scss b/packages/styles/scss/components/callout-with-media/_callout-with-media.scss index 075e9f678da..0961dc54be7 100644 --- a/packages/styles/scss/components/callout-with-media/_callout-with-media.scss +++ b/packages/styles/scss/components/callout-with-media/_callout-with-media.scss @@ -15,7 +15,6 @@ @use '../../internal/content-block'; @use '../../internal/content-item/content-item'; @use '../image'; -@use '../image-with-caption'; @use '../content-block-simple/content-block-simple'; @mixin callout-with-media { diff --git a/packages/styles/scss/components/card-in-card/_card-in-card.scss b/packages/styles/scss/components/card-in-card/_card-in-card.scss index e413eb65cb5..662fedd7e53 100644 --- a/packages/styles/scss/components/card-in-card/_card-in-card.scss +++ b/packages/styles/scss/components/card-in-card/_card-in-card.scss @@ -96,7 +96,7 @@ } ::slotted(svg[slot='icon']) { - @extend .#{$prefix}--image__icon; + @extend :host(#{$dds-prefix}-image::slotted(svg[slot='icon'])); @include breakpoint(md) { right: calc(75% - #{$spacing-07}); diff --git a/packages/styles/scss/components/content-block-media/_content-block-media.scss b/packages/styles/scss/components/content-block-media/_content-block-media.scss index 8654629d6bc..014da58686b 100644 --- a/packages/styles/scss/components/content-block-media/_content-block-media.scss +++ b/packages/styles/scss/components/content-block-media/_content-block-media.scss @@ -15,7 +15,6 @@ @use '../card'; @use '../content-group-simple/index'; @use '../image'; -@use '../image-with-caption'; @use '../feature-card'; @mixin themed-items { diff --git a/packages/styles/scss/components/content-block-segmented/_content-block-segmented.scss b/packages/styles/scss/components/content-block-segmented/_content-block-segmented.scss index 9a9a813b1d8..787d48c2052 100755 --- a/packages/styles/scss/components/content-block-segmented/_content-block-segmented.scss +++ b/packages/styles/scss/components/content-block-segmented/_content-block-segmented.scss @@ -12,7 +12,7 @@ @use '../../internal/content-block'; @use '../../internal/content-group'; @use '../../internal/content-item/content-item'; -@use '../image-with-caption'; +@use '../image'; @mixin content-block-segmented { :host(#{$dds-prefix}-content-block-segmented), diff --git a/packages/styles/scss/components/image-with-caption/_image-with-caption.scss b/packages/styles/scss/components/image-with-caption/_image-with-caption.scss deleted file mode 100644 index 8419e92ada8..00000000000 --- a/packages/styles/scss/components/image-with-caption/_image-with-caption.scss +++ /dev/null @@ -1,101 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 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/motion' as *; -@use '@carbon/styles/scss/spacing' as *; -@use '@carbon/styles/scss/theme' as *; -@use '@carbon/styles/scss/type' as *; -@use '../../globals/vars' as *; -@use '../image'; -@use '../lightbox-media-viewer/lightbox-media-viewer'; - -@mixin image-with-caption { - .#{$prefix}--image-with-caption, - :host(#{$dds-prefix}-image)[heading] { - display: block; - margin-top: $spacing-07; - margin-bottom: $spacing-07; - max-width: carbon--mini-units(80); - - @include breakpoint(md) { - margin-top: $spacing-07; - margin-bottom: $spacing-07; - } - } - - .#{$prefix}--image-with-caption__image { - display: block; - width: 100%; - padding: 0; - position: relative; - pointer-events: none; - border: none; - background-color: transparent; - - &:hover { - // only have lightbox functionality on bigger breakpoints - @include breakpoint(md) { - cursor: pointer; - - .#{$prefix}--image__img, - #{$dds-prefix}-image { - filter: brightness(80%); - } - - .#{$prefix}--image-with-caption__zoom-button { - background-color: rgba(0, 0, 0, 1); - } - } - } - - &:hover, - &:focus { - // only have lightbox functionality on bigger breakpoints - @include breakpoint(md) { - outline: $spacing-01 solid $focus; - } - } - } - - .#{$prefix}--image-with-caption__zoom-button { - display: none; - - // only have lightbox functionality on bigger breakpoints - @include breakpoint(md) { - width: $spacing-09; - height: $spacing-09; - display: flex; - position: absolute; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.5); - - svg { - margin: auto; - fill: $icon-on-color; - } - } - } - - .#{$prefix}--image-with-caption__image, - .#{$prefix}--image-with-caption__zoom-button { - // only have lightbox functionality on bigger breakpoints - @include breakpoint(md) { - transition: $duration-moderate-01 motion(standard, productive); - pointer-events: auto; - } - } - - .#{$prefix}--image__caption { - @include type-style('caption-02'); - - margin-top: $spacing-03; - color: $text-helper; - } -} diff --git a/packages/styles/scss/components/image-with-caption/_index.scss b/packages/styles/scss/components/image-with-caption/_index.scss deleted file mode 100644 index cc2a896c183..00000000000 --- a/packages/styles/scss/components/image-with-caption/_index.scss +++ /dev/null @@ -1,11 +0,0 @@ -// -// Copyright IBM Corp. 2018, 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. -// - -@forward 'image-with-caption'; -@use 'image-with-caption'; - -@include image-with-caption.image-with-caption; diff --git a/packages/styles/scss/components/image/_image.scss b/packages/styles/scss/components/image/_image.scss index 8d1a0848884..d891fd65273 100644 --- a/packages/styles/scss/components/image/_image.scss +++ b/packages/styles/scss/components/image/_image.scss @@ -10,10 +10,38 @@ @use '@carbon/styles/scss/config' as *; @use '@carbon/styles/scss/spacing' as *; @use '@carbon/styles/scss/theme' as *; +@use '@carbon/styles/scss/breakpoint' as *; +@use '@carbon/styles/scss/motion' as *; +@use '@carbon/styles/scss/type' as *; +@use '@carbon/colors' as *; +@use '../lightbox-media-viewer/lightbox-media-viewer'; @mixin image { - .#{$prefix}--image { + :host(#{$dds-prefix}-card-cta-image), + :host(#{$dds-prefix}-image) { position: relative; + display: block; + } + + :host(#{$dds-prefix}-card-cta-image::slotted(svg[slot='icon'])), + :host(#{$dds-prefix}-image::slotted(svg[slot='icon'])) { + position: absolute; + top: calc(50% - #{$spacing-07}); + right: calc(50% - #{$spacing-07}); + } + + :host(#{$dds-prefix}-image-item) { + display: none; + } + + :host(#{$dds-prefix}-card-cta-image) { + @include ratio-base(4, 3, true); + + .#{$prefix}--image__img { + position: absolute; + height: 100%; + top: 0; + } } .#{$prefix}--image__img { @@ -36,10 +64,109 @@ overflow: hidden; } - .#{$prefix}--image__icon { - position: absolute; - top: calc(50% - #{$spacing-07}); - right: calc(50% - #{$spacing-07}); + :host(#{$dds-prefix}-image)[heading] { + display: block; + margin-top: $spacing-07; + margin-bottom: $spacing-07; + max-width: carbon--mini-units(80); + + @include breakpoint(md) { + margin-top: $spacing-07; + margin-bottom: $spacing-07; + } + } + + .#{$prefix}--image-with-caption__image { + display: block; + width: 100%; + padding: 0; + position: relative; + pointer-events: none; + border: 1px solid $border-tile-01; + background-color: transparent; + + &:hover { + // only have lightbox functionality on bigger breakpoints + @include breakpoint(md) { + cursor: zoom-in; + + .#{$prefix}--image__img { + filter: brightness(80%); + } + + .#{$prefix}--image-with-caption__zoom-button { + background-color: rgba($gray-100, 1); + } + } + } + + &:focus { + // only have lightbox functionality on bigger breakpoints + @include breakpoint(md) { + outline: $spacing-01 solid $focus; + border: 1px solid $focus-inset; + } + } + } + + .#{$prefix}--image-with-caption__zoom-button { + display: none; + + // only have lightbox functionality on bigger breakpoints + @include breakpoint(md) { + width: $spacing-09; + height: $spacing-09; + display: flex; + position: absolute; + right: 0; + bottom: 0; + background-color: rgba($gray-100, 0.85); + + svg { + margin: auto; + fill: $white; + } + } + } + + .#{$prefix}--image-with-caption__image, + .#{$prefix}--image-with-caption__zoom-button { + // only have lightbox functionality on bigger breakpoints + @include breakpoint(md) { + transition: $duration-moderate-01 motion(standard, productive); + pointer-events: auto; + } + } + + .#{$prefix}--image__caption { + @include type-style('body-01'); + + margin-top: $spacing-03; + color: $text-helper; + } + + :host(#{$dds-prefix}-image[lightbox-contrast='dark']) { + .#{$prefix}--image-with-caption__zoom-button { + background-color: rgba($white, 0.85); + + svg { + fill: $gray-90; + } + } + .#{$prefix}--image-with-caption__image { + &:hover { + // only have lightbox functionality on bigger breakpoints + @include breakpoint(md) { + .#{$prefix}--image__img { + filter: brightness(120%); + } + + .#{$prefix}--image-with-caption__zoom-button { + background-color: rgba($white, 1); + } + } + } + } } // dds-image-logo style. diff --git a/packages/styles/scss/components/leadspace-block/_leadspace-block.scss b/packages/styles/scss/components/leadspace-block/_leadspace-block.scss index 94a3aac6a67..5a8faa5fc1c 100644 --- a/packages/styles/scss/components/leadspace-block/_leadspace-block.scss +++ b/packages/styles/scss/components/leadspace-block/_leadspace-block.scss @@ -15,7 +15,7 @@ @use '../../globals/vars' as *; @use '../button-group'; @use '../link-list'; -@use '../image-with-caption'; +@use '../image'; @use '../../internal/content-block'; %leadspace-block-padding { diff --git a/packages/styles/scss/ibm-dotcom-styles.scss b/packages/styles/scss/ibm-dotcom-styles.scss index d284cb72938..dc5a4307c06 100644 --- a/packages/styles/scss/ibm-dotcom-styles.scss +++ b/packages/styles/scss/ibm-dotcom-styles.scss @@ -42,7 +42,6 @@ @use 'components/footer'; @use 'components/horizontal-rule'; @use 'components/image'; -@use 'components/image-with-caption'; @use 'components/layout'; @use 'components/leadspace'; @use 'components/leadspace-block'; diff --git a/packages/web-components/examples/codesandbox/components/content-block-media/cdn.html b/packages/web-components/examples/codesandbox/components/content-block-media/cdn.html index 1f649101043..420ed54766d 100644 --- a/packages/web-components/examples/codesandbox/components/content-block-media/cdn.html +++ b/packages/web-components/examples/codesandbox/components/content-block-media/cdn.html @@ -39,7 +39,7 @@ Lorem ipsum dolor sit amet - - + Lorem ipsum dolor sit amet. diff --git a/packages/web-components/examples/codesandbox/components/content-block-media/index.html b/packages/web-components/examples/codesandbox/components/content-block-media/index.html index 94f0d205d25..7617613e19f 100644 --- a/packages/web-components/examples/codesandbox/components/content-block-media/index.html +++ b/packages/web-components/examples/codesandbox/components/content-block-media/index.html @@ -37,7 +37,7 @@ Lorem ipsum dolor sit amet - - + Lorem ipsum dolor sit amet. diff --git a/packages/web-components/src/components/content-block-mixed/index.ts b/packages/web-components/src/components/content-block-mixed/index.ts index 151eb4de8f6..2f2de33629f 100644 --- a/packages/web-components/src/components/content-block-mixed/index.ts +++ b/packages/web-components/src/components/content-block-mixed/index.ts @@ -16,6 +16,5 @@ import '../content-group/content-group-copy'; import '../content-item/index'; import '../cta/card-link-cta'; import '../image/image'; -import '../image-with-caption/image-with-caption'; import '../link-list/index'; import '../pictogram-item/index'; diff --git a/packages/web-components/src/components/expressive-modal/expressive-modal.scss b/packages/web-components/src/components/expressive-modal/expressive-modal.scss index dcfd1e8ec23..7b736d0f567 100644 --- a/packages/web-components/src/components/expressive-modal/expressive-modal.scss +++ b/packages/web-components/src/components/expressive-modal/expressive-modal.scss @@ -16,17 +16,13 @@ :host(#{$dds-prefix}-expressive-modal) { @extend :host(#{$prefix}-modal); - &[open] { - @extend :host(#{$prefix}-modal[open]); - } - &[expressive-size='full-width'] { .#{$prefix}--modal-container { max-height: none; @include breakpoint(md) { - width: calc(100% - $spacing-07); - height: calc(100% - $spacing-07); + width: calc(100% - $spacing-10); + height: calc(100% - $spacing-10); } .#{$prefix}--modal-content { @@ -57,6 +53,11 @@ } } +:host(#{$dds-prefix}-expressive-modal[open]) { + @extend .#{$prefix}--modal; + @extend .is-visible; +} + :host(#{$dds-prefix}-expressive-modal-header), :host(#{$dds-prefix}-expressive-modal-heading), :host(#{$dds-prefix}-expressive-modal-footer) { diff --git a/packages/web-components/src/components/image-with-caption/image-with-caption.scss b/packages/web-components/src/components/image-with-caption/image-with-caption.scss deleted file mode 100644 index 08992cf45b3..00000000000 --- a/packages/web-components/src/components/image-with-caption/image-with-caption.scss +++ /dev/null @@ -1,13 +0,0 @@ -// -// Copyright IBM Corp. 2020 -// -// 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/components/image-with-caption'; -@use '@carbon/ibmdotcom-styles/scss/globals/vars' as *; - -:host(#{$dds-prefix}-image-with-caption) { - outline: none; -} diff --git a/packages/web-components/src/components/image-with-caption/image-with-caption.ts b/packages/web-components/src/components/image-with-caption/image-with-caption.ts deleted file mode 100644 index 7c9ca5bd0ab..00000000000 --- a/packages/web-components/src/components/image-with-caption/image-with-caption.ts +++ /dev/null @@ -1,196 +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 on from 'carbon-components/es/globals/js/misc/on.js'; -import { ifDefined } from 'lit/directives/if-defined.js'; -import FocusMixin from '../../internal/vendor/@carbon/web-components/globals/mixins/focus.js'; -import '../expressive-modal/expressive-modal'; -import '../expressive-modal/expressive-modal-close-button'; -import '../image/image'; -import '../lightbox-media-viewer/lightbox-image-viewer'; -import '../button/button'; -import ZoomIn20 from '../../internal/vendor/@carbon/web-components/icons/zoom--in/20.js'; -import deprecate from '../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/deprecate/deprecate'; -import settings from '../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; -import styles from './image-with-caption.scss'; -import ModalRenderMixin from '../../globals/mixins/modal-render'; -import Handle from '../../globals/internal/handle'; -import StableSelectorMixin from '../../globals/mixins/stable-selector'; -import { carbonElement as customElement } from '../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element.js'; - -const { prefix, stablePrefix: ddsPrefix } = settings; - -/** - * Image With Caption - * - * @element dds-image-with-caption - */ - -@customElement(`${ddsPrefix}-image-with-caption`) -class DDSImageWithCaption extends StableSelectorMixin( - ModalRenderMixin(FocusMixin(LitElement)) -) { - /** - * `true` handles re-opening after model is closed - * - * @private - */ - private _handleClick() { - this.open = true; - } - - /** - * The handler of `${ddsPrefix}-expressive-modal-closed` event from ``. - */ - private _handleCloseModal = () => { - this.open = false; - }; - - /** - * The handle for the listener of `${ddsPrefix}-expressive-modal-closed` event. - */ - private _hCloseModal: Handle | null = null; - - /** - * The lightbox. - */ - @property({ type: Boolean, reflect: true }) - lightbox = false; - - /** - * The image source. - */ - @property({ reflect: true, attribute: 'default-src' }) - defaultSrc = ''; - - /** - * The alt text. - */ - @property({ reflect: true }) - alt = ''; - - /** - * The heading. - */ - @property({ reflect: true }) - heading = ''; - - @property({ attribute: 'launch-lightbox-button-assistive-text' }) - launchLightboxButtonAssistiveText = 'launch light box media viewer'; - - /** - * The description. - */ - @property({ reflect: true }) - copy = ''; - - /** - * `true` if the modal should be open. - */ - @property({ type: Boolean, reflect: true }) - open = false; - - connectedCallback() { - super.connectedCallback(); - this.modalRenderRoot = this.createModalRenderRoot(); // Creates modal render root up-front to hook the event listener - // Manually hooks the event listeners on the modal render root to make the event names configurable - this._hCloseModal = on( - this.modalRenderRoot, - (this.constructor as typeof DDSImageWithCaption).eventCloseModal, - this._handleCloseModal as EventListener - ); - } - - disconnectedCallback() { - if (this._hCloseModal) { - this._hCloseModal = this._hCloseModal.release(); - } - super.disconnectedCallback(); - } - - render() { - const { - alt, - defaultSrc, - heading, - launchLightboxButtonAssistiveText, - lightbox, - _handleClick: handleClick, - } = this; - return html` - ${lightbox - ? html` - - ` - : html` - - `} -

${heading}

- `; - } - - renderModal() { - const { alt, copy, defaultSrc, heading, lightbox, open } = this; - return !lightbox - ? undefined - : html` - - - - - - `; - } - - /** - * The name of the custom event fired after the modal is closed upon a user gesture. - */ - static get eventCloseModal() { - return `${ddsPrefix}-expressive-modal-closed`; - } - - static get stableSelector() { - return `${ddsPrefix}--image-with-caption`; - } - - static shadowRootOptions = { - ...LitElement.shadowRootOptions, - delegatesFocus: true, - }; - static styles = styles; -} - -export default deprecate( - /* @__GENERATE_REACT_CUSTOM_ELEMENT_TYPE__ */ - DDSImageWithCaption, - 'The dds-image-with-caption component has been merged with the dds-image component ' + - 'See dds-image documentation for more information.' -); diff --git a/packages/web-components/src/components/image/__stories__/image.stories.react.tsx b/packages/web-components/src/components/image/__stories__/image.stories.react.tsx index 1c37d9cc530..050e0695b08 100644 --- a/packages/web-components/src/components/image/__stories__/image.stories.react.tsx +++ b/packages/web-components/src/components/image/__stories__/image.stories.react.tsx @@ -16,36 +16,72 @@ import DDSImage from '@carbon/ibmdotcom-web-components/es/components-react/image import DDSImageItem from '@carbon/ibmdotcom-web-components/es/components-react/image/image-item'; import readme from './README.stories.react.mdx'; -import imgLg2x1 from '../../../../../storybook-images/assets/720/fpo--2x1--720x360--005.jpg'; import imgLg16x9 from '../../../../../storybook-images/assets/720/fpo--16x9--720x405--005.jpg'; -import imgSm2x1 from '../../../../../storybook-images/assets/320/fpo--2x1--320x160--005.jpg'; +import imgLg2x1 from '../../../../../storybook-images/assets/720/fpo--2x1--720x360--005.jpg'; +import imgLg3x2 from '../../../../../storybook-images/assets/720/fpo--3x2--720x480--005.jpg'; +import imgLg4x3 from '../../../../../storybook-images/assets/720/fpo--4x3--720x540--005.jpg'; +import imgLg1x1 from '../../../../../storybook-images/assets/720/fpo--1x1--720x720--005.jpg'; +import imgMd16x9 from '../../../../../storybook-images/assets/480/fpo--16x9--480x270--005.jpg'; import imgMd2x1 from '../../../../../storybook-images/assets/480/fpo--2x1--480x240--005.jpg'; +import imgMd3x2 from '../../../../../storybook-images/assets/480/fpo--3x2--480x320--005.jpg'; +import imgMd4x3 from '../../../../../storybook-images/assets/480/fpo--4x3--480x360--005.jpg'; +import imgMd1x1 from '../../../../../storybook-images/assets/480/fpo--1x1--480x480--005.jpg'; import imgSm16x9 from '../../../../../storybook-images/assets/320/fpo--16x9--320x180--005.jpg'; -import imgMd16x9 from '../../../../../storybook-images/assets/480/fpo--16x9--480x270--005.jpg'; +import imgSm2x1 from '../../../../../storybook-images/assets/320/fpo--2x1--320x160--005.jpg'; +import imgSm3x2 from '../../../../../storybook-images/assets/320/fpo--3x2--320x213--005.jpg'; +import imgSm4x3 from '../../../../../storybook-images/assets/320/fpo--4x3--320x160--004.jpg'; +import imgSm1x1 from '../../../../../storybook-images/assets/320/fpo--1x1--320x320--005.jpg'; +import chartSvg from './chart-svg.js'; import textNullable from '../../../../.storybook/knob-text-nullable'; +import { LIGHTBOX_CONTRAST } from '../image'; + +const contrasts = { + light: LIGHTBOX_CONTRAST.LIGHT, + dark: LIGHTBOX_CONTRAST.DARK, +}; const images = { '2:1': imgLg2x1, '16:9': imgLg16x9, + '3:2': imgLg3x2, + '4:3': imgLg4x3, + '1:1': imgLg1x1, + 'SVG (transparent background)': chartSvg, }; const srcsets = { '2:1': [imgSm2x1, imgMd2x1, imgLg2x1], '16:9': [imgSm16x9, imgMd16x9, imgLg16x9], + '3:2': [imgSm3x2, imgMd3x2, imgLg3x2], + '4x3': [imgSm4x3, imgMd4x3, imgLg4x3], + '1x1': [imgSm1x1, imgMd1x1, imgLg1x1], }; + export const Default = args => { - const { alt, defaultSrc, heading, copy, border, lightbox } = args?.Image ?? {}; - // TODO: See if we can fix unwanted `&` to `&` conversion upon changing the select knob - const srcset = srcsets[defaultSrc?.replace(/&/, '&')]; + const { + alt, + defaultSrc, + heading, + copy, + border, + lightbox, + lightboxContrast, + longDescription, } = args?.Image ?? {}; + + const ratio = String(Object.keys(images).find(key => images[key] === defaultSrc)); + const srcset = srcsets[ratio]; + return ( + lightbox={lightbox || undefined} + lightbox-contrast={lightboxContrast}> + {!longDescription ? '' :
{longDescription}
} {!srcset ? ( undefined ) : ( @@ -62,14 +98,31 @@ export const Default = args => { Default.story = { parameters: { knobs: { - Image: () => ({ - alt: textNullable('Alt text', 'Image alt text'), - defaultSrc: select('Default image (default-src)', images, imgLg2x1), - lightbox: boolean('Lightbox (lightbox)', false), - border: boolean('Border', false), - copy: textNullable('Copy (copy)', 'Lorem ipsum dolor sit amet'), - heading: textNullable('Heading (heading)', ''), - }), + Image: () => { + const alt = textNullable('Alt text', 'Image alt text'); + const defaultSrc = select('Default image (default-src)', images, imgLg2x1); + const border = boolean('Border', false); + const copy = textNullable('Copy (copy)', 'Lorem ipsum dolor sit amet'); + const heading = textNullable('Heading (heading)', 'This is a caption'); + const longDescription = textNullable( + 'Long Description', + 'Optional long descriptive text that is visually hidden to help screen reader users.' + ); + const lightbox = boolean('Lightbox (lightbox)', false); + const lightboxContrast = lightbox + ? select('Lightbox contrast', contrasts, LIGHTBOX_CONTRAST.LIGHT) + : ''; + return { + alt, + defaultSrc, + border, + copy, + heading, + longDescription, + lightbox, + lightboxContrast, + }; + }, }, }, }; diff --git a/packages/web-components/src/components/image/__stories__/image.stories.ts b/packages/web-components/src/components/image/__stories__/image.stories.ts index 1d5aba68011..7a314117b13 100644 --- a/packages/web-components/src/components/image/__stories__/image.stories.ts +++ b/packages/web-components/src/components/image/__stories__/image.stories.ts @@ -14,28 +14,57 @@ import { select, boolean } from '@storybook/addon-knobs'; // eslint-disable-next-line sort-imports import imgLg16x9 from '../../../../../storybook-images/assets/720/fpo--16x9--720x405--005.jpg'; import imgLg2x1 from '../../../../../storybook-images/assets/720/fpo--2x1--720x360--005.jpg'; +import imgLg3x2 from '../../../../../storybook-images/assets/720/fpo--3x2--720x480--005.jpg'; +import imgLg4x3 from '../../../../../storybook-images/assets/720/fpo--4x3--720x540--005.jpg'; +import imgLg1x1 from '../../../../../storybook-images/assets/720/fpo--1x1--720x720--005.jpg'; import imgMd16x9 from '../../../../../storybook-images/assets/480/fpo--16x9--480x270--005.jpg'; import imgMd2x1 from '../../../../../storybook-images/assets/480/fpo--2x1--480x240--005.jpg'; +import imgMd3x2 from '../../../../../storybook-images/assets/480/fpo--3x2--480x320--005.jpg'; +import imgMd4x3 from '../../../../../storybook-images/assets/480/fpo--4x3--480x360--005.jpg'; +import imgMd1x1 from '../../../../../storybook-images/assets/480/fpo--1x1--480x480--005.jpg'; import imgSm16x9 from '../../../../../storybook-images/assets/320/fpo--16x9--320x180--005.jpg'; import imgSm2x1 from '../../../../../storybook-images/assets/320/fpo--2x1--320x160--005.jpg'; +import imgSm3x2 from '../../../../../storybook-images/assets/320/fpo--3x2--320x213--005.jpg'; +import imgSm4x3 from '../../../../../storybook-images/assets/320/fpo--4x3--320x160--004.jpg'; +import imgSm1x1 from '../../../../../storybook-images/assets/320/fpo--1x1--320x320--005.jpg'; import chartSvg from './chart-svg.js'; import readme from './README.stories.mdx'; import textNullable from '../../../../.storybook/knob-text-nullable'; +import { LIGHTBOX_CONTRAST } from '../image'; + +const contrasts = { + light: LIGHTBOX_CONTRAST.LIGHT, + dark: LIGHTBOX_CONTRAST.DARK, +}; const images = { '2:1': imgLg2x1, '16:9': imgLg16x9, + '3:2': imgLg3x2, + '4:3': imgLg4x3, + '1:1': imgLg1x1, 'SVG (transparent background)': chartSvg, }; const srcsets = { '2:1': [imgSm2x1, imgMd2x1, imgLg2x1], '16:9': [imgSm16x9, imgMd16x9, imgLg16x9], + '3:2': [imgSm3x2, imgMd3x2, imgLg3x2], + '4x3': [imgSm4x3, imgMd4x3, imgLg4x3], + '1x1': [imgSm1x1, imgMd1x1, imgLg1x1], }; export const Default = (args) => { - const { alt, defaultSrc, heading, copy, border, lightbox, longDescription } = - args?.['dds-image'] ?? {}; + const { + alt, + defaultSrc, + heading, + copy, + border, + lightbox, + lightboxContrast, + longDescription, + } = args?.['dds-image'] ?? {}; // TODO: See if we can fix unwanted `&` to `&` conversion upon changing the select knob const srcset = srcsets[defaultSrc?.replace(/&/, '&')]; return html` @@ -45,6 +74,7 @@ export const Default = (args) => { default-src="${ifDefined(defaultSrc)}" ?border=${border} ?lightbox="${lightbox}" + lightbox-contrast="${lightboxContrast}" copy="${ifDefined(copy)}"> ${!longDescription ? undefined @@ -79,18 +109,35 @@ export default { ...readme.parameters, hasStoryPadding: true, knobs: { - 'dds-image': () => ({ - alt: textNullable('Alt text', 'Image alt text'), - defaultSrc: select('Default image (default-src)', images, imgLg2x1), - lightbox: boolean('Lightbox (lightbox)', false), - border: boolean('Border', false), - copy: textNullable('Copy (copy)', 'Lorem ipsum dolor sit amet'), - heading: textNullable('Heading (heading)', 'This is a caption'), - longDescription: textNullable( + 'dds-image': () => { + const alt = textNullable('Alt text', 'Image alt text'); + const defaultSrc = select( + 'Default image (default-src)', + images, + imgLg2x1 + ); + const border = boolean('Border', false); + const copy = textNullable('Copy (copy)', 'Lorem ipsum dolor sit amet'); + const heading = textNullable('Heading (heading)', 'This is a caption'); + const longDescription = textNullable( 'Long Description', 'Optional long descriptive text that is visually hidden to help screen reader users.' - ), - }), + ); + const lightbox = boolean('Lightbox (lightbox)', false); + const lightboxContrast = lightbox + ? select('Lightbox contrast', contrasts, LIGHTBOX_CONTRAST.LIGHT) + : ''; + return { + alt, + defaultSrc, + border, + copy, + heading, + longDescription, + lightbox, + lightboxContrast, + }; + }, }, propsSet: { default: { diff --git a/packages/web-components/src/components/image-with-caption/index.ts b/packages/web-components/src/components/image/defs.ts similarity index 54% rename from packages/web-components/src/components/image-with-caption/index.ts rename to packages/web-components/src/components/image/defs.ts index 0e190c22f05..936a2bf3299 100644 --- a/packages/web-components/src/components/image-with-caption/index.ts +++ b/packages/web-components/src/components/image/defs.ts @@ -7,4 +7,17 @@ * LICENSE file in the root directory of this source tree. */ -import './image-with-caption'; +/** + * Image lightbox contrast + */ +export enum LIGHTBOX_CONTRAST { + /** + * Light (default). + */ + LIGHT = 'light', + + /** + * Dark. + */ + DARK = 'dark', +} diff --git a/packages/web-components/src/components/image/image.scss b/packages/web-components/src/components/image/image.scss index c99b1921389..5d081a7b38b 100644 --- a/packages/web-components/src/components/image/image.scss +++ b/packages/web-components/src/components/image/image.scss @@ -5,33 +5,4 @@ // LICENSE file in the root directory of this source tree. // -@use '@carbon/styles/scss/config' as *; @use '@carbon/ibmdotcom-styles/scss/components/image'; -@use '@carbon/ibmdotcom-styles/scss/components/image-with-caption'; -@use '@carbon/ibmdotcom-styles/scss/globals/utils/ratio-base' as *; -@use '@carbon/ibmdotcom-styles/scss/globals/vars' as *; - -:host(#{$dds-prefix}-card-cta-image), -:host(#{$dds-prefix}-image) { - @extend .#{$prefix}--image; - - display: block; - - ::slotted(svg[slot='icon']) { - @extend .#{$prefix}--image__icon; - } -} - -:host(#{$dds-prefix}-image-item) { - display: none; -} - -:host(#{$dds-prefix}-card-cta-image) { - @include ratio-base(4, 3, true); - - .#{$prefix}--image__img { - position: absolute; - height: 100%; - top: 0; - } -} diff --git a/packages/web-components/src/components/image/image.ts b/packages/web-components/src/components/image/image.ts index 33632ba5d3f..2093e1cca4d 100644 --- a/packages/web-components/src/components/image/image.ts +++ b/packages/web-components/src/components/image/image.ts @@ -17,7 +17,8 @@ import '../expressive-modal/expressive-modal'; import '../expressive-modal/expressive-modal-close-button'; import '../lightbox-media-viewer/lightbox-image-viewer'; import '../button/button'; -import ZoomIn20 from '../../internal/vendor/@carbon/web-components/icons/zoom--in/20.js'; +import { LIGHTBOX_CONTRAST } from './defs'; +import Maximize20 from '../../internal/vendor/@carbon/web-components/icons/maximize/20.js'; import settings from '../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; import styles from './image.scss'; import ModalRenderMixin from '../../globals/mixins/modal-render'; @@ -27,6 +28,8 @@ import { carbonElement as customElement } from '../../internal/vendor/@carbon/we const { prefix, stablePrefix: ddsPrefix } = settings; +export { LIGHTBOX_CONTRAST }; + /** * Image. * @@ -106,6 +109,12 @@ class DDSImage extends StableSelectorMixin( @property({ type: Boolean, reflect: true }) border = false; + /** + * The lightbox contrast option. + */ + @property({ attribute: 'lightbox-contrast' }) + lightboxContrast = LIGHTBOX_CONTRAST.LIGHT; + /** * The lightbox. */ @@ -156,12 +165,13 @@ class DDSImage extends StableSelectorMixin( alt, border, defaultSrc, + lightbox, _images: images, _handleSlotChange: handleSlotChange, } = this; const imgClasses = classMap({ [`${prefix}--image__img`]: true, - [`${prefix}--image__img--border`]: border, + [`${prefix}--image__img--border`]: border && !lightbox, }); return html` @@ -221,7 +231,7 @@ class DDSImage extends StableSelectorMixin( @click="${handleClick}"> ${this.renderImage()}
- ${ZoomIn20()} + ${Maximize20()}
` diff --git a/packages/web-components/tests/snapshots/dds-card-section-offset.md b/packages/web-components/tests/snapshots/dds-card-section-offset.md index 81608a54501..1f48884c2ca 100644 --- a/packages/web-components/tests/snapshots/dds-card-section-offset.md +++ b/packages/web-components/tests/snapshots/dds-card-section-offset.md @@ -7,7 +7,7 @@ ``` -
+
@@ -25,7 +25,7 @@ ``` -
+
diff --git a/packages/web-components/tests/snapshots/dds-carousel.md b/packages/web-components/tests/snapshots/dds-carousel.md index ec891cca2b1..3a794c05648 100644 --- a/packages/web-components/tests/snapshots/dds-carousel.md +++ b/packages/web-components/tests/snapshots/dds-carousel.md @@ -11,7 +11,7 @@ >