diff --git a/src/elements/notification/notification.stories.ts b/src/elements/notification/notification.stories.ts index 4685e5688d..c4d188627e 100644 --- a/src/elements/notification/notification.stories.ts +++ b/src/elements/notification/notification.stories.ts @@ -47,10 +47,10 @@ const animation: InputType = { const basicArgTypes: ArgTypes = { 'title-content': titleContent, - type: type, - size: size, - readonly: readonly, - animation: animation, + type, + size, + readonly, + animation, }; const basicArgs: Args = { diff --git a/src/elements/notification/notification.ts b/src/elements/notification/notification.ts index 4c70978cbc..153c6427f0 100644 --- a/src/elements/notification/notification.ts +++ b/src/elements/notification/notification.ts @@ -50,19 +50,13 @@ export class SbbNotificationElement extends LitElement { didClose: 'didClose', } as const; - /** - * The type of the notification. - */ + /** The type of the notification. */ @property({ reflect: true }) public type: 'info' | 'success' | 'warn' | 'error' = 'info'; - /** - * Content of title. - */ + /** Content of title. */ @property({ attribute: 'title-content', reflect: true }) public titleContent?: string; - /** - * Level of title, it will be rendered as heading tag (e.g. h3). Defaults to level 3. - */ + /** Level of title, it will be rendered as heading tag (e.g. h3). Defaults to level 3. */ @property({ attribute: 'title-level' }) public titleLevel: SbbTitleLevel = '3'; /** @@ -74,14 +68,10 @@ export class SbbNotificationElement extends LitElement { /** Size variant, either s or m. */ @property({ reflect: true }) public size: 'm' | 's' = 'm'; - /** - * The enabled animations. - */ + /** The enabled animations. */ @property({ reflect: true }) public animation: 'open' | 'close' | 'all' | 'none' = 'all'; - /** - * The state of the notification. - */ + /** The state of the notification. */ private set _state(state: SbbOpenedClosedState) { this.setAttribute('data-state', state); } @@ -175,14 +165,15 @@ export class SbbNotificationElement extends LitElement { clearTimeout(this._resizeObserverTimeout); } - this.toggleAttribute('data-resize-disable-animation', true); - this._setNotificationHeight(); - // Disable the animation when resizing the notification to avoid strange height transition effects. + this.toggleAttribute('data-resize-disable-animation', true); this._resizeObserverTimeout = setTimeout( () => this.removeAttribute('data-resize-disable-animation'), DEBOUNCE_TIME, ); + + // To avoid ResizeObserver loops, we set the height a tick later. + setTimeout(() => this._setNotificationHeight()); } private _onNotificationAnimationEnd(event: AnimationEvent): void { diff --git a/src/elements/notification/notification.visual.spec.ts b/src/elements/notification/notification.visual.spec.ts new file mode 100644 index 0000000000..f7759e5520 --- /dev/null +++ b/src/elements/notification/notification.visual.spec.ts @@ -0,0 +1,84 @@ +import { html, nothing, type TemplateResult } from 'lit'; +import { repeat } from 'lit/directives/repeat.js'; + +import { describeEach, describeViewports, visualDiffDefault } from '../core/testing/private.js'; + +import '../link/link.js'; +import './notification.js'; + +describe(`sbb-notification`, () => { + const defaultArgs = { + type: 'info', + size: 'm', + readonly: false, + title: true, + slotted: false, + }; + + const notificationTemplate = ({ + type, + size, + readonly, + title, + slotted, + }: typeof defaultArgs): TemplateResult => html` + + ${title && slotted ? html`Slotted title` : nothing} The quick brown + fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.  + Link one + Link two + Link three + + `; + + const textTemplate = html` +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut + labore et dolore magna aliqua. Link +

+ `; + + const states = { + readonly: [false, true], + slottedTitle: [false, true], + }; + + const types = ['info', 'success', 'warn', 'error']; + const visualStates = { + state: [...types.map((type) => ({ type, multiple: false })), { multiple: true, type: 'all' }], + size: ['s', 'm'], + }; + + describeViewports({ viewports: ['zero', 'small', 'medium'] }, () => { + describeEach(states, ({ readonly, slottedTitle }) => { + it( + visualDiffDefault.name, + visualDiffDefault.with(async (setup) => { + const args = { ...defaultArgs, readonly, title: slottedTitle, slotted: slottedTitle }; + await setup.withFixture(html`${notificationTemplate(args)} ${textTemplate}`); + }), + ); + }); + + describeEach(visualStates, ({ state, size }) => { + it( + visualDiffDefault.name, + visualDiffDefault.with(async (setup) => { + await setup.withFixture(html` + ${repeat( + state.multiple ? types : [state.type], + (type: string) => html`${notificationTemplate({ ...defaultArgs, type, size })}`, + )} + ${textTemplate} + `); + }), + ); + }); + }); +}); diff --git a/tools/web-test-runner/preload-icons.ts b/tools/web-test-runner/preload-icons.ts index 14f308f258..cf28705343 100644 --- a/tools/web-test-runner/preload-icons.ts +++ b/tools/web-test-runner/preload-icons.ts @@ -28,6 +28,7 @@ const preloadIconList = [ 'chevron-small-right-small', 'chevron-small-up-small', 'circle-cross-small', + 'circle-exclamation-point-small', 'circle-information-large', 'circle-information-medium', 'circle-information-small',