diff --git a/packages/ibm-products-web-components/src/components/about-modal/_story-assets/ansible-logo.png b/packages/ibm-products-web-components/src/components/about-modal/_story-assets/ansible-logo.png new file mode 100644 index 0000000000..c3e9f49a89 Binary files /dev/null and b/packages/ibm-products-web-components/src/components/about-modal/_story-assets/ansible-logo.png differ diff --git a/packages/ibm-products-web-components/src/components/about-modal/_story-assets/example-logo.svg b/packages/ibm-products-web-components/src/components/about-modal/_story-assets/example-logo.svg new file mode 100644 index 0000000000..1026d9dbf4 --- /dev/null +++ b/packages/ibm-products-web-components/src/components/about-modal/_story-assets/example-logo.svg @@ -0,0 +1,22 @@ + + + + Group + Created with Sketch. + + + + + + + + + + + + + + + + + diff --git a/packages/ibm-products-web-components/src/components/about-modal/_story-assets/grafana-logo.png b/packages/ibm-products-web-components/src/components/about-modal/_story-assets/grafana-logo.png new file mode 100644 index 0000000000..c8659494f8 Binary files /dev/null and b/packages/ibm-products-web-components/src/components/about-modal/_story-assets/grafana-logo.png differ diff --git a/packages/ibm-products-web-components/src/components/about-modal/_story-assets/js-logo.png b/packages/ibm-products-web-components/src/components/about-modal/_story-assets/js-logo.png new file mode 100644 index 0000000000..d9393792c4 Binary files /dev/null and b/packages/ibm-products-web-components/src/components/about-modal/_story-assets/js-logo.png differ diff --git a/packages/ibm-products-web-components/src/components/about-modal/about-modal.mdx b/packages/ibm-products-web-components/src/components/about-modal/about-modal.mdx new file mode 100644 index 0000000000..51a923d8ec --- /dev/null +++ b/packages/ibm-products-web-components/src/components/about-modal/about-modal.mdx @@ -0,0 +1,32 @@ +import { ArgTypes, Markdown, Meta } from '@storybook/blocks'; +import { cdnJs, cdnCss } from '../../globals/internal/storybook-cdn'; +import * as AboutModalStories from './about-modal.stories'; + + + +# Tearsheet + +Tearsheets keep users in-context of a page while performing tasks like +navigating, editing, viewing details, or configuring something new. + +## Getting started + +Here's a quick example to get you started. + +### JS (via import) + +```javascript +import '@carbon/ibm-products-web-components/es/components/about-modal/index.js'; +``` + + +### HTML + +```html + + +``` + +## `` attributes, properties and events + + diff --git a/packages/ibm-products-web-components/src/components/about-modal/about-modal.scss b/packages/ibm-products-web-components/src/components/about-modal/about-modal.scss new file mode 100644 index 0000000000..e6d30a58d0 --- /dev/null +++ b/packages/ibm-products-web-components/src/components/about-modal/about-modal.scss @@ -0,0 +1,117 @@ +/* +* Copyright IBM Corp. 2023, 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. +*/ + +$css--plex: true !default; + +/* Other Carbon settings. */ +@use '@carbon/styles' as styles; +@use '@carbon/styles/scss/reset'; +@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/themes/scss/themes'; +@use '@carbon/styles/scss/theme' as *; +@use '@carbon/styles/scss/type'; +@use '@carbon/styles/scss/utilities'; +@use '@carbon/styles/scss/utilities/ai-gradient' as *; +@use '@carbon/styles/scss/components/modal' as *; +@use '@carbon/styles/scss/utilities/convert' as *; +@use 'sass:map'; + +$prefix: 'c4p'; +$carbon-prefix: 'cds'; + +@use '@carbon/ibm-products-styles/scss/components/AboutModal/index' as *; + +:host(#{$prefix}-about-modal) { + .#{$prefix}--about-modal__logo { + margin: $spacing-05 $spacing-05 $spacing-07 $spacing-05; + } + #{$carbon-prefix}-modal-header { + padding: 0 20% 0 $spacing-05; + grid-row: auto; + margin-block-end: 0; + } + #{$carbon-prefix}-modal-body { + @include type.type-style('body-compact-02'); + + overflow: hidden auto; + grid-row: auto; + min-block-size: $spacing-10; + padding-block-start: 0; + padding-inline: $spacing-05 20%; + &:not(.#{$prefix}--about-modal-scroll-content) { + margin-block-end: $spacing-06; + padding-block-end: 0; + } + &.#{$prefix}--about-modal-scroll-content { + @extend .#{$carbon-prefix}--modal-scroll-content; + } + } + + #{$carbon-prefix}-modal-heading { + @include type.type-style('heading-04'); + + color: $text-primary; + margin-block-end: $spacing-02; + } + + .#{$prefix}--about-modal__version { + color: $text-secondary; + } + + .#{$prefix}--about-modal__content, + .#{$prefix}--about-modal__copyright-text { + @include type.type-style('label-01'); + + color: $text-secondary; + margin-block: $spacing-06 0; + } + + .#{$prefix}--about-modal__copyright-text { + margin-block-start: $spacing-05; + } + + .#{$prefix}--about-modal__content:first-child, + .#{$prefix}--about-modal__copyright-text:first-child { + margin-block-start: $spacing-07; + } + #{$carbon-prefix}-link { + display: inline-flex; + } + .#{$prefix}--about-modal__links-container { + @include type.type-style('body-compact-01'); + + margin-block-start: $spacing-06; + #{$carbon-prefix}-link + #{$carbon-prefix}-link { + border-inline-start: 1px solid $border-strong-01; + margin-inline-start: $spacing-03; + padding-inline-start: $spacing-03; + } + } + #{$carbon-prefix}-modal-footer { + @include styles.theme(styles.$g100); + + display: block; + padding: $spacing-05; + background-color: $layer-02; + block-size: auto; + .#{$prefix}--about-modal__footer-label { + @include type.type-style('label-01'); + + color: $text-secondary; + margin-block-end: $spacing-02; + } + .#{$prefix}--about-modal__footer--tech-logo { + block-size: $spacing-06; + inline-size: $spacing-06; + margin-inline-end: $spacing-03; + object-fit: contain; + } + } +} diff --git a/packages/ibm-products-web-components/src/components/about-modal/about-modal.stories.ts b/packages/ibm-products-web-components/src/components/about-modal/about-modal.stories.ts new file mode 100644 index 0000000000..1762b34298 --- /dev/null +++ b/packages/ibm-products-web-components/src/components/about-modal/about-modal.stories.ts @@ -0,0 +1,279 @@ +/** + * @license + * + * Copyright IBM Corp. 2024, 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 { html, TemplateResult } from 'lit'; +import './index'; +import { prefix } from '../../globals/settings'; +import '@carbon/web-components/es/components/button/index.js'; +import styles from './story-styles.scss?lit'; +import ExampleLogo from './_story-assets/example-logo.svg'; +import ansibleLogo from './_story-assets/ansible-logo.png'; +import grafanaLogo from './_story-assets/grafana-logo.png'; +import jsLogo from './_story-assets/js-logo.png'; +import '@carbon/web-components/es/components/link/index.js'; + +const storyPrefix = 'about-modal-stories__'; +const blockClass = `${prefix}--about-modal`; +const openModal = () => { + document.querySelector(`${prefix}-about-modal`)?.setAttribute('open', ''); +}; + +const argTypes = { + closeIconDescription: { + control: 'text', + description: 'The accessibility title for the close icon.', + }, + copyrightText: { + control: 'text', + description: + 'Trademark and copyright information. Displays first year of product release to current year.', + }, + logo: { + control: false, + description: 'A visual symbol used to represent the product.', + }, + title: { + control: 'select', + description: 'label', + options: { + 'No label': 0, + 'Shorter label': 1, + 'Longer label': 2, + }, + }, + version: { + control: 'text', + description: + 'Text that provides information on the version number of your product.', + }, + additionalInfo: { + control: 'select', + description: + 'If you are legally required to display logos of technologies used to build your product you can provide this in the additionalInfo. Additional information will be displayed in the footer.', + options: { + 'no additional info': 0, + 'powered by logos': 1, + }, + }, + content: { + control: 'select', + description: + 'Subhead text providing any relevant product disclaimers including legal information (optional)', + options: { + 'no content': 0, + 'short content': 1, + 'medium content': 2, + 'long content': 3, + }, + }, + links: { + control: 'select', + description: + 'An array of Carbon `Link` component if there are additional information to call out within the card. The about modal should be used to display the product information and not where users go to find help (optional) text providing any relevant product disclaimers including legal information (optional)', + options: { + none: 0, + 'one link': 1, + 'two links': 2, + 'three links': 3, + }, + }, + modalAriaLabel: { + control: 'text', + description: 'Specifies aria label for AboutModal', + }, +}; + +const logo = html` + Example product or service logo +`; + +const getTitle = (index) => { + switch (index) { + case 0: + return html`IBM Product name`; + case 1: + return html`IBM Product name example that is longer than one line`; + case 2: + return html`IBM Product name`; + default: + return null; + } +}; + +const getAdditionalInfo = (index) => { + switch (index) { + case 1: + return html` + + Grafana + Ansible + JavaScript + `; + default: + return null; + } +}; + +const getContent = (index) => { + switch (index) { + case 1: + return html`This Web site contains proprietary notices and copyright + information, the terms of which must be observed and followed.`; + case 2: + return html`This Web site contains proprietary notices and copyright + information, the terms of which must be observed and followed. Please see + the tab entitled 'Copyright and trademark information' for related + information. IBM grants you a non-exclusive, non-transferable, limited + permission to access and display the Web pages within this site as a + customer or potential customer of IBM provided you comply with these Terms + of Use, and all copyright, trademark, and other proprietary notices remain + intact.`; + case 3: + return html`This Web site contains proprietary notices and copyright + information, the terms of which must be observed and followed. Please see + the tab entitled 'Copyright and trademark information' for related + information. IBM grants you a non-exclusive, non-transferable, limited + permission to access and display the Web pages within this site as a + customer or potential customer of IBM provided you comply with these Terms + of Use, and all copyright, trademark, and other proprietary notices remain + intact. You may only use a crawler to crawl this Web site as permitted by + this Web site's robots.txt protocol, and IBM may block any crawlers in its + sole discretion. The use authorized under this agreement is non-commercial + in nature (e.g., you may not sell the content you access on or through + this Web site.) All other use of this site is prohibited. Except for the + limited permission in the preceding paragraph, IBM does not grant you any + express or implied rights or licenses under any patents, trademarks, + copyrights, or other proprietary or intellectual property rights. You may + not mirror any of the content from this site on another Web site or in any + other media. Any software and other materials that are made available for + downloading, access, or other use from this site with their own license + terms will be governed by such terms, conditions, and notices. Your + failure to comply with such terms or any of the terms on this site will + result in automatic termination of any rights granted to you, without + prior notice, and you must immediately destroy all copies of downloaded + materials in your possession, custody or control. This Web site contains + proprietary notices and copyright information, the terms of which must be + observed and followed. Please see the tab entitled “Copyright and + trademark information” for related information. IBM grants you a + non-exclusive, non-transferable, limited permission to access and display + the Web pages within this site as a customer or potential customer of IBM + provided you comply with these Terms of Use, and all copyright, trademark, + and other proprietary notices remain intact. You may only use a crawler to + crawl this Web site as permitted by this Web site’s robots.txt protocol, + and IBM may block any crawlers in its sole discretion. The use authorized + under this agreement is non-commercial in nature (e.g., you may not sell + the content you access on or through this Web site.) All other use of this + site is prohibited. Except for the limited permission in the preceding + paragraph, IBM does not grant you any express or implied rights or + licenses under any patents, trademarks, copyrights, or other proprietary + or intellectual property rights. You may not mirror any of the content + from this site on another Web site or in any other media. Any software and + other materials that are made available for downloading, access, or other + use from this site with their own license terms will be governed by such + terms, conditions, and notices. Your failure to comply with such terms or + any of the terms on this site will result in automatic termination of any + rights granted to you, without prior notice, and you must immediately + destroy all copies of downloaded materials in your possession, custody or + control.`; + default: + return null; + } +}; + +const getLinks = (index) => { + if (index > 0) { + const links: TemplateResult[] = []; + for (let i = 0; i < index; i++) { + const link = html` Link action `; + links.push(link); + } + return links; + } else { + return null; + } +}; + +const renderTemplate = (args) => { + return html` + +
+
+
+ Reopen the About Modal +
+
+ + `; +}; + +export const Default = { + args: { + closeIconDescription: 'close', + copyrightText: 'Copyright © IBM Corp. 2020, 2023', + logo: logo, + title: 2, + version: 'Version 0.0.0', + additionalInfo: 0, + content: 0, + links: 0, + modalAriaLabel: '', + }, + argTypes, + render: renderTemplate, +}; + +export const AboutModalWithAllPropsSet = { + args: { + closeIconDescription: 'close', + copyrightText: 'Copyright © IBM Corp. 2020, 2023', + logo: logo, + title: 2, + version: 'Version 0.0.0', + additionalInfo: 1, + content: 2, + links: 3, + modalAriaLabel: '', + }, + argTypes, + render: renderTemplate, +}; + +const meta = { + title: 'Experimental/AboutModal', +}; + +export default meta; diff --git a/packages/ibm-products-web-components/src/components/about-modal/about-modal.test.ts b/packages/ibm-products-web-components/src/components/about-modal/about-modal.test.ts new file mode 100644 index 0000000000..a33df9a8bc --- /dev/null +++ b/packages/ibm-products-web-components/src/components/about-modal/about-modal.test.ts @@ -0,0 +1,21 @@ +/** + * Copyright IBM Corp. 2024, 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. + */ + +vi.mock('@carbon/icons/lib/close/20', () => vi.fn().mockReturnValue({})); +import { describe, expect, it, vi } from 'vitest'; +import { render, html } from 'lit'; + +const template = () => html` `; + +describe('c4p-about-modal', () => { + it('should render about modal', async () => { + render(template(), document.body); + await Promise.resolve(); + const elem = document.body.querySelector('c4p-about-modal' as any); + expect(elem).toBeDefined(); + }); +}); diff --git a/packages/ibm-products-web-components/src/components/about-modal/about-modal.ts b/packages/ibm-products-web-components/src/components/about-modal/about-modal.ts new file mode 100644 index 0000000000..fbbb7741ec --- /dev/null +++ b/packages/ibm-products-web-components/src/components/about-modal/about-modal.ts @@ -0,0 +1,158 @@ +/** + * @license + * + * Copyright IBM Corp. 2023, 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 { LitElement, html } from 'lit'; +import { property, query, state } from 'lit/decorators.js'; +import { prefix } from '../../globals/settings'; +import HostListenerMixin from '@carbon/web-components/es/globals/mixins/host-listener.js'; +import '@carbon/web-components/es/components/modal/index.js'; +import styles from './about-modal.scss?lit'; +import { carbonElement as customElement } from '@carbon/web-components/es/globals/decorators/carbon-element.js'; +const blockClass = `${prefix}--about-modal`; + +/** + * About Modal. + * + * @element c4p-about-modal + * @csspart dialog The dialog. + * @fires c4p-about-modal-beingclosed + * The custom event fired before this about modal is being closed upon a user gesture. + * Cancellation of this event stops the user-initiated action of closing this about modal. + * @fires c4p-about-modal-closed - The custom event fired after this about modal is closed upon a user gesture. + */ +@customElement(`${prefix}-about-modal`) +class CDSAboutModal extends HostListenerMixin(LitElement) { + /** + * Determines if About Modal is open or not. + */ + @property({ reflect: true, type: Boolean }) + open = true; + + /** + * Determines if About Modal is open or not. + */ + @property({ type: String }) + closeIconDescription = 'close'; + + /** + * Determines if About Modal is open or not. + */ + @property({ type: String }) + copyrightText; + + /** + * A visual symbol used to represent the product. + */ + @property() + logo; + + /** + * Text that provides information on the version number of your product. + */ + @property({ type: String }) + version; + + /** + * Header text that provides the product name. The IBM Services logo consists of two discrete, but required, elements: the iconic IBM 8-bar logo represented alongside the IBM Services logotype. Please follow these guidelines to ensure proper execution. + */ + @property() + title; + + /** + * If you are legally required to display logos of technologies used to build your product you can provide this in the additionalInfo. Additional information will be displayed in the footer. + */ + @property() + additionalInfo; + + /** + * Subhead text providing any relevant product disclaimers including legal information (optional) + */ + @property() + content; + + /** + * An array of Carbon `Link` component if there are additional information to call out within the card. The about modal should be used to display the product information and not where users go to find help (optional) + */ + @property() + links; + /** + * To check if the modal body is overflowing or not. + */ + @state() private isOverflowing = false; + + @query('cds-modal-body') private container!: HTMLElement; + + firstUpdated() { + this._checkOverflow(); + } + + updated() { + this._checkOverflow(); + } + render() { + const { + open, + closeIconDescription, + _handleClose: handleClose, + logo, + title, + version, + additionalInfo, + content, + links, + copyrightText, + } = this; + return html` + +
${logo}
+ + + ${title} + + +
+
${version}
+ ${links && + links.length > 0 && + html` `} + ${content && + html`

${content}

`} + ${copyrightText && + html` + + `} +
+
+ ${additionalInfo && + html` ${additionalInfo} `} +
+ `; + } + private _handleClose = () => { + this.open = false; + }; + + private _checkOverflow() { + if (this.container) { + this.isOverflowing = + this.container.scrollHeight > this.container.clientHeight; + } + } + + static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader +} + +export default CDSAboutModal; diff --git a/packages/ibm-products-web-components/src/components/about-modal/defs.ts b/packages/ibm-products-web-components/src/components/about-modal/defs.ts new file mode 100644 index 0000000000..43d1c83717 --- /dev/null +++ b/packages/ibm-products-web-components/src/components/about-modal/defs.ts @@ -0,0 +1,8 @@ +/** + * @license + * + * Copyright IBM Corp. 2023, 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/ibm-products-web-components/src/components/about-modal/index.ts b/packages/ibm-products-web-components/src/components/about-modal/index.ts new file mode 100644 index 0000000000..981c81b7de --- /dev/null +++ b/packages/ibm-products-web-components/src/components/about-modal/index.ts @@ -0,0 +1,10 @@ +/** + * @license + * + * Copyright IBM Corp. 2024, 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 './about-modal'; diff --git a/packages/ibm-products-web-components/src/components/about-modal/story-styles.scss b/packages/ibm-products-web-components/src/components/about-modal/story-styles.scss new file mode 100644 index 0000000000..4e5d074ff6 --- /dev/null +++ b/packages/ibm-products-web-components/src/components/about-modal/story-styles.scss @@ -0,0 +1,34 @@ +/* +* Copyright IBM Corp. 2023, 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/styles/scss/spacing' as *; +@use '@carbon/styles/scss/config' as *; + +$story-prefix: 'about-modal-stories__'; + +.#{$story-prefix}body-content { + display: flex; + flex-direction: column; + padding: $spacing-05; + gap: $spacing-05; +} + +.#{$story-prefix}story-container { + position: fixed; + display: grid; + block-size: 100vh; + grid-template-rows: 3rem 1fr; + inline-size: 100vw; + inset-block-start: 0; + inset-inline-start: 0; +} + +.#{$story-prefix}story-content { + position: relative; + display: flex; + align-items: center; + justify-content: center; +} diff --git a/packages/ibm-products-web-components/src/index.ts b/packages/ibm-products-web-components/src/index.ts index 5f266a65c0..467e94f5e3 100644 --- a/packages/ibm-products-web-components/src/index.ts +++ b/packages/ibm-products-web-components/src/index.ts @@ -9,3 +9,4 @@ export { default as CDSSidePanel } from './components/side-panel/side-panel'; export { default as CDSTearsheet } from './components/tearsheet/tearsheet'; +export { default as CDSAboutModal } from './components/about-modal/about-modal';