diff --git a/src/components/notification/__snapshots__/notification.spec.snap.js b/src/components/notification/__snapshots__/notification.spec.snap.js index ea2dd63639..125eb322ca 100644 --- a/src/components/notification/__snapshots__/notification.spec.snap.js +++ b/src/components/notification/__snapshots__/notification.spec.snap.js @@ -1,7 +1,70 @@ /* @web/test-runner snapshot v1 */ export const snapshots = {}; -snapshots["sbb-notification renders"] = +snapshots["sbb-notification A11y tree Chrome"] = +`

+ { + "role": "WebArea", + "name": "", + "children": [ + { + "role": "heading", + "name": "Test title", + "level": 3 + }, + { + "role": "text", + "name": "Lorem ipsum ..." + }, + { + "role": "button", + "name": "Close message" + } + ] +} +

+`; +/* end snapshot sbb-notification A11y tree Chrome */ + +snapshots["sbb-notification A11y tree Firefox"] = +`

+ { + "role": "document", + "name": "", + "children": [ + { + "role": "heading", + "name": "Test title", + "level": 3 + }, + { + "role": "text leaf", + "name": "Lorem ipsum ..." + }, + { + "role": "button", + "name": "Close message" + } + ] +} +

+`; +/* end snapshot sbb-notification A11y tree Firefox */ + +snapshots["sbb-notification renders Dom"] = +` + The quick brown fox jumps over the lazy dog. + +`; +/* end snapshot sbb-notification renders Dom */ + +snapshots["sbb-notification renders ShadowDom"] = `
`; -/* end snapshot sbb-notification renders */ +/* end snapshot sbb-notification renders ShadowDom */ -snapshots["sbb-notification renders with a title"] = +snapshots["sbb-notification renders with a title Dom"] = +` + The quick brown fox jumps over the lazy dog. + +`; +/* end snapshot sbb-notification renders with a title Dom */ + +snapshots["sbb-notification renders with a title ShadowDom"] = `
`; -/* end snapshot sbb-notification renders with a title */ +/* end snapshot sbb-notification renders with a title ShadowDom */ + +snapshots["sbb-notification renders with a slotted title Dom"] = +` + + Slotted title + + The quick brown fox jumps over the lazy dog. + +`; +/* end snapshot sbb-notification renders with a slotted title Dom */ -snapshots["sbb-notification renders with a slotted title"] = +snapshots["sbb-notification renders with a slotted title ShadowDom"] = `
`; -/* end snapshot sbb-notification renders with a slotted title */ +/* end snapshot sbb-notification renders with a slotted title ShadowDom */ + +snapshots["sbb-notification renders without the close button Dom"] = +` + The quick brown fox jumps over the lazy dog. + +`; +/* end snapshot sbb-notification renders without the close button Dom */ -snapshots["sbb-notification renders without the close button"] = +snapshots["sbb-notification renders without the close button ShadowDom"] = `
`; -/* end snapshot sbb-notification renders without the close button */ +/* end snapshot sbb-notification renders without the close button ShadowDom */ -snapshots["sbb-notification A11y tree Chrome"] = -`

- { - "role": "WebArea", - "name": "", - "children": [ - { - "role": "heading", - "name": "Test title", - "level": 3 - }, - { - "role": "text", - "name": "Lorem ipsum ..." - }, - { - "role": "button", - "name": "Close message" - } - ] -} -

+snapshots["sbb-notification renders size s Dom"] = +` + The quick brown fox jumps over the lazy dog. + `; -/* end snapshot sbb-notification A11y tree Chrome */ +/* end snapshot sbb-notification renders size s Dom */ -snapshots["sbb-notification A11y tree Firefox"] = -`

- { - "role": "document", - "name": "", - "children": [ - { - "role": "heading", - "name": "Test title", - "level": 3 - }, - { - "role": "text leaf", - "name": "Lorem ipsum ..." - }, - { - "role": "button", - "name": "Close message" - } - ] -} -

+snapshots["sbb-notification renders size s ShadowDom"] = +`
+
+ + + + + Title + + + + + + + + + + + +
+
`; -/* end snapshot sbb-notification A11y tree Firefox */ +/* end snapshot sbb-notification renders size s ShadowDom */ diff --git a/src/components/notification/notification.scss b/src/components/notification/notification.scss index 5c2b3be9dd..591c0fc2a2 100644 --- a/src/components/notification/notification.scss +++ b/src/components/notification/notification.scss @@ -13,6 +13,7 @@ --sbb-notification-padding-inline: var(--sbb-spacing-responsive-xs); --sbb-notification-color: var(--sbb-color-charcoal); --sbb-notification-icon-color: var(--sbb-notification-type-color); + --sbb-notification-icon-margin-block-start: 0; --sbb-notification-border-width: var(--sbb-border-width-1x); --sbb-notification-border: var(--sbb-notification-border-width) solid var(--sbb-notification-type-color); @@ -33,6 +34,8 @@ border var(--sbb-notification-animation-duration) var(--sbb-animation-duration-2x) var(--sbb-notification-timing-function), opacity var(--sbb-notification-animation-duration) var(--sbb-notification-timing-function); + --sbb-notification-content-padding-inline: var(--sbb-spacing-responsive-xxxs) + var(--sbb-spacing-responsive-xs); // As the notification has always a light background, we have to fix the focus outline color // to default color for cases where the notification is used in a negative context. @@ -94,6 +97,37 @@ --sbb-notification-type-color-sass: #{color.mix(sbb-tokens.$sbb-color-red, white, 5%)}; } +:host([size='s']) { + --sbb-notification-padding-block: var(--sbb-spacing-responsive-xxxs); + --sbb-notification-padding-inline: var(--sbb-spacing-responsive-xxs) + var(--sbb-spacing-responsive-xxxs); + --sbb-notification-content-padding-inline: var(--sbb-spacing-responsive-xxxs) + var(--sbb-spacing-responsive-xxs); +} + +@include sbb.mq($from: small) { + :host { + --sbb-notification-icon-margin-block-start: calc( + ((1em * var(--sbb-typo-line-height-body-text)) - var(--sbb-size-icon-ui-small)) / 2 + ); + } + + :host(:where([data-slot-names~='title'], [title-content])) { + --sbb-notification-icon-margin-block-start: calc( + ( + (var(--sbb-font-size-title-5) * var(--sbb-typo-line-height-body-text)) - var( + --sbb-size-icon-ui-small + ) + ) / 2 + ); + } + + :host([size='s']) { + --sbb-notification-padding-inline: var(--sbb-spacing-responsive-xxs); + --sbb-notification-icon-margin-block-start: 0; + } +} + .sbb-notification__wrapper { position: relative; margin: var(--sbb-notification-margin); @@ -150,26 +184,15 @@ grid-template-columns: auto 1fr auto; align-items: flex-start; } + + :host([size='s']) & { + @include sbb.text-xs--regular; + } } .sbb-notification__icon { color: var(--sbb-notification-icon-color); - - @include sbb.mq($from: small) { - margin-block-start: calc( - ((1em * var(--sbb-typo-line-height-body-text)) - var(--sbb-size-icon-ui-small)) / 2 - ); - - :host(:where([data-slot-names~='title'], [title-content])) & { - margin-block-start: calc( - ( - (var(--sbb-font-size-title-5) * var(--sbb-typo-line-height-body-text)) - var( - --sbb-size-icon-ui-small - ) - ) / 2 - ); - } - } + margin-block-start: var(--sbb-notification-icon-margin-block-start); } .sbb-notification__title { @@ -190,7 +213,7 @@ order: initial; grid-area: initial; margin-block-start: 0; - padding-inline: var(--sbb-spacing-responsive-xxxs) var(--sbb-spacing-responsive-xs); + padding-inline: var(--sbb-notification-content-padding-inline); } } diff --git a/src/components/notification/notification.spec.ts b/src/components/notification/notification.spec.ts index 27bacda083..3cb04fdb27 100644 --- a/src/components/notification/notification.spec.ts +++ b/src/components/notification/notification.spec.ts @@ -2,83 +2,108 @@ import { expect } from '@open-wc/testing'; import { html } from 'lit/static-html.js'; import { fixture, testA11yTreeSnapshot } from '../core/testing/private.js'; -import { waitForCondition } from '../core/testing.js'; +import type { SbbNotificationElement } from './notification.js'; import './notification.js'; describe(`sbb-notification`, () => { - it('renders', async () => { - const root = await fixture( - html`The quick brown fox jumps over the lazy dog.`, - ); - await waitForCondition(() => root.getAttribute('data-state') === 'opened'); - - expect(root).dom.to.be.equal( - ` - - The quick brown fox jumps over the lazy dog. - `, - { ignoreAttributes: ['style'] }, - ); - await expect(root).shadowDom.to.be.equalSnapshot(); + describe('renders', () => { + let element: SbbNotificationElement; + + beforeEach(async () => { + element = await fixture( + html`The quick brown fox jumps over the lazy dog.`, + ); + }); + + it('Dom', async () => { + await expect(element).dom.to.be.equalSnapshot({ ignoreAttributes: ['style'] }); + }); + + it('ShadowDom', async () => { + await expect(element).shadowDom.to.be.equalSnapshot(); + }); }); - it('renders with a title', async () => { - const root = await fixture( - html`The quick brown fox jumps over the lazy dog.`, - ); - await waitForCondition(() => root.getAttribute('data-state') === 'opened'); - - expect(root).dom.to.be.equal( - ` - - The quick brown fox jumps over the lazy dog. - `, - { ignoreAttributes: ['style'] }, - ); - await expect(root).shadowDom.to.be.equalSnapshot(); + describe('renders with a title', () => { + let element: SbbNotificationElement; + + beforeEach(async () => { + element = await fixture( + html`The quick brown fox jumps over the lazy dog.`, + ); + }); + + it('Dom', async () => { + await expect(element).dom.to.be.equalSnapshot({ ignoreAttributes: ['style'] }); + }); + + it('ShadowDom', async () => { + await expect(element).shadowDom.to.be.equalSnapshot(); + }); }); - it('renders with a slotted title', async () => { - const root = await fixture( - html`Slotted title - The quick brown fox jumps over the lazy dog. - `, - ); - await waitForCondition(() => root.getAttribute('data-state') === 'opened'); - - expect(root).dom.to.be.equal( - ` - - - Slotted title - - The quick brown fox jumps over the lazy dog. - `, - { ignoreAttributes: ['style'] }, - ); - await expect(root).shadowDom.to.be.equalSnapshot(); + describe('renders with a slotted title', () => { + let element: SbbNotificationElement; + + beforeEach(async () => { + element = await fixture( + html`Slotted title + The quick brown fox jumps over the lazy dog. + `, + ); + }); + + it('Dom', async () => { + await expect(element).dom.to.be.equalSnapshot({ ignoreAttributes: ['style'] }); + }); + + it('ShadowDom', async () => { + await expect(element).shadowDom.to.be.equalSnapshot(); + }); }); - it('renders without the close button', async () => { - const root = await fixture( - html`The quick brown fox jumps over the lazy dog.`, - ); - await waitForCondition(() => root.getAttribute('data-state') === 'opened'); - - expect(root).dom.to.be.equal( - ` - - The quick brown fox jumps over the lazy dog. - `, - { ignoreAttributes: ['style'] }, - ); - await expect(root).shadowDom.to.be.equalSnapshot(); + describe('renders without the close button', () => { + let element: SbbNotificationElement; + + beforeEach(async () => { + element = await fixture( + html`The quick brown fox jumps over the lazy dog.`, + ); + }); + + it('Dom', async () => { + await expect(element).dom.to.be.equalSnapshot({ ignoreAttributes: ['style'] }); + }); + + it('ShadowDom', async () => { + await expect(element).shadowDom.to.be.equalSnapshot(); + }); + }); + + describe('renders size s', () => { + let element: SbbNotificationElement; + + beforeEach(async () => { + element = await fixture( + html`The quick brown fox jumps over the lazy dog.`, + ); + }); + + it('Dom', async () => { + await expect(element).dom.to.be.equalSnapshot({ ignoreAttributes: ['style'] }); + }); + + it('ShadowDom', async () => { + await expect(element).shadowDom.to.be.equalSnapshot(); + }); }); testA11yTreeSnapshot( diff --git a/src/components/notification/notification.stories.ts b/src/components/notification/notification.stories.ts index 9888e5e349..61d0cee57a 100644 --- a/src/components/notification/notification.stories.ts +++ b/src/components/notification/notification.stories.ts @@ -25,6 +25,13 @@ const type: InputType = { options: ['info', 'success', 'warn', 'error'], }; +const size: InputType = { + control: { + type: 'inline-radio', + }, + options: ['s', 'm'], +}; + const readonly: InputType = { control: { type: 'boolean', @@ -41,6 +48,7 @@ const animation: InputType = { const basicArgTypes: ArgTypes = { 'title-content': titleContent, type: type, + size: size, readonly: readonly, animation: animation, }; @@ -48,6 +56,7 @@ const basicArgTypes: ArgTypes = { const basicArgs: Args = { 'title-content': 'Title', type: type.options![0], + size: size.options![1], readonly: false, animation: animation.options![0], }; @@ -60,6 +69,7 @@ const appendNotification = (event: Event, args: Args): void => { ); newNotification.titleContent = args['title-content']; newNotification.type = args['type']; + newNotification.size = args['size']; newNotification.readonly = args['readonly']; newNotification.animation = args['animation']; newNotification.innerHTML = @@ -169,6 +179,12 @@ export const Readonly: StoryObj = { args: { ...basicArgs, readonly: true }, }; +export const SizeS: StoryObj = { + render: DefaultTemplate, + argTypes: basicArgTypes, + args: { ...basicArgs, size: 's' }, +}; + export const NoTitle: StoryObj = { render: DefaultTemplate, argTypes: basicArgTypes, diff --git a/src/components/notification/notification.ts b/src/components/notification/notification.ts index 9d9e767a9c..5a52bc62a1 100644 --- a/src/components/notification/notification.ts +++ b/src/components/notification/notification.ts @@ -67,6 +67,9 @@ export class SbbNotificationElement extends LitElement { */ @property({ reflect: true, type: Boolean }) public readonly = false; + /** Size variant, either s or m. */ + @property({ reflect: true }) public size: 'm' | 's' = 'm'; + /** * The enabled animations. */ @@ -221,7 +224,11 @@ export class SbbNotificationElement extends LitElement { > - + ${this.titleContent} @@ -231,7 +238,7 @@ export class SbbNotificationElement extends LitElement { ? html` this.close()} aria-label=${i18nCloseNotification[this._language.current]} diff --git a/src/components/notification/readme.md b/src/components/notification/readme.md index 69cabf4eba..00d6245f0c 100644 --- a/src/components/notification/readme.md +++ b/src/components/notification/readme.md @@ -86,6 +86,7 @@ As a base rule, opening animations should be active if a notification arrives af | `titleContent` | `title-content` | public | `string \| undefined` | | Content of title. | | `titleLevel` | `title-level` | public | `SbbTitleLevel` | `'3'` | Level of title, it will be rendered as heading tag (e.g. h3). Defaults to level 3. | | `readonly` | `readonly` | public | `boolean` | `false` | Whether the notification is readonly. In readonly mode, there is no dismiss button offered to the user. | +| `size` | `size` | public | `'m' \| 's'` | `'m'` | Size variant, either s or m. | | `animation` | `animation` | public | `'open' \| 'close' \| 'all' \| 'none'` | `'all'` | The enabled animations. | ## Methods