From 1f107a0cad33764a4be2c32b84fcceb81342aca5 Mon Sep 17 00:00:00 2001 From: Jeri Peier Date: Thu, 15 Aug 2024 14:13:34 +0200 Subject: [PATCH] fix(sbb-flip-card): fix accessibility issues (#3000) Closes #2983 --- src/elements/core/i18n/i18n.ts | 2 +- .../flip-card-summary.snapshot.spec.snap.js | 6 +- .../flip-card-summary/flip-card-summary.scss | 3 + .../flip-card-summary.snapshot.spec.ts | 10 +-- .../flip-card-summary.stories.ts | 3 +- .../flip-card-summary.visual.spec.ts | 9 +- .../flip-card/flip-card-summary/readme.md | 2 +- .../flip-card.snapshot.spec.snap.js | 46 +++++----- .../flip-card/flip-card/flip-card.scss | 27 +++++- .../flip-card/flip-card.snapshot.spec.ts | 16 ++-- .../flip-card/flip-card/flip-card.spec.ts | 81 +++++++++++++++--- .../flip-card/flip-card/flip-card.ssr.spec.ts | 37 ++++++++- .../flip-card/flip-card/flip-card.stories.ts | 83 +++++++++++-------- src/elements/flip-card/flip-card/flip-card.ts | 82 ++++++++++++------ .../flip-card/flip-card.visual.spec.ts | 32 ++++--- src/elements/flip-card/flip-card/readme.md | 20 ++--- 16 files changed, 303 insertions(+), 156 deletions(-) diff --git a/src/elements/core/i18n/i18n.ts b/src/elements/core/i18n/i18n.ts index a25727e02c..f048ea40c1 100644 --- a/src/elements/core/i18n/i18n.ts +++ b/src/elements/core/i18n/i18n.ts @@ -638,7 +638,7 @@ export const i18nFlipCard: Record = { export const i18nReverseCard: Record = { de: 'Klicken Sie auf diese Karte, um zurück zur Zusammenfassung zu gelangen', - en: 'Click on this card to go back to summary', + en: 'Click on this card to go back to the summary', fr: 'Cliquez sur cette carte pour revenir au résumé', it: 'Clicca su questa scheda per tornare al sommario', }; diff --git a/src/elements/flip-card/flip-card-summary/__snapshots__/flip-card-summary.snapshot.spec.snap.js b/src/elements/flip-card/flip-card-summary/__snapshots__/flip-card-summary.snapshot.spec.snap.js index 22189347f7..ee7b5f5bcc 100644 --- a/src/elements/flip-card/flip-card-summary/__snapshots__/flip-card-summary.snapshot.spec.snap.js +++ b/src/elements/flip-card/flip-card-summary/__snapshots__/flip-card-summary.snapshot.spec.snap.js @@ -31,9 +31,9 @@ snapshots["sbb-flip-card-summary DOM"] = Summary diff --git a/src/elements/flip-card/flip-card-summary/flip-card-summary.scss b/src/elements/flip-card/flip-card-summary/flip-card-summary.scss index 6aaaa56024..465e9cfddf 100644 --- a/src/elements/flip-card/flip-card-summary/flip-card-summary.scss +++ b/src/elements/flip-card/flip-card-summary/flip-card-summary.scss @@ -76,6 +76,9 @@ } ::slotted(sbb-image) { + --sbb-image-border-radius: 0; + --sbb-image-aspect-ratio: auto; + width: 100%; height: 100%; } diff --git a/src/elements/flip-card/flip-card-summary/flip-card-summary.snapshot.spec.ts b/src/elements/flip-card/flip-card-summary/flip-card-summary.snapshot.spec.ts index 03eaf3a04b..6351e4af15 100644 --- a/src/elements/flip-card/flip-card-summary/flip-card-summary.snapshot.spec.ts +++ b/src/elements/flip-card/flip-card-summary/flip-card-summary.snapshot.spec.ts @@ -1,7 +1,6 @@ import { expect } from '@open-wc/testing'; import { html } from 'lit/static-html.js'; -import sampleImages from '../../core/images.js'; import { fixture, testA11yTreeSnapshot } from '../../core/testing/private.js'; import type { SbbFlipCardSummaryElement } from './flip-card-summary.js'; @@ -10,6 +9,8 @@ import './flip-card-summary.js'; import '../../title.js'; import '../../image.js'; +const imageUrl = import.meta.resolve('../../core/testing/assets/placeholder-image.png'); + describe(`sbb-flip-card-summary`, () => { let element: SbbFlipCardSummaryElement; @@ -17,12 +18,7 @@ describe(`sbb-flip-card-summary`, () => { element = await fixture( html` Summary - + `, ); }); diff --git a/src/elements/flip-card/flip-card-summary/flip-card-summary.stories.ts b/src/elements/flip-card/flip-card-summary/flip-card-summary.stories.ts index 0cc2544136..09995780ba 100644 --- a/src/elements/flip-card/flip-card-summary/flip-card-summary.stories.ts +++ b/src/elements/flip-card/flip-card-summary/flip-card-summary.stories.ts @@ -54,8 +54,7 @@ const Template = (args: Args): TemplateResult => html` diff --git a/src/elements/flip-card/flip-card-summary/flip-card-summary.visual.spec.ts b/src/elements/flip-card/flip-card-summary/flip-card-summary.visual.spec.ts index e4cad132a7..623548ee40 100644 --- a/src/elements/flip-card/flip-card-summary/flip-card-summary.visual.spec.ts +++ b/src/elements/flip-card/flip-card-summary/flip-card-summary.visual.spec.ts @@ -21,12 +21,7 @@ const imageBase64 = await loadAssetAsBase64( const images = [ { selector: 'sbb-image', - image: html``, + image: html``, }, { selector: 'img', @@ -57,7 +52,7 @@ describe(`sbb-flip-card-summary`, () => { 'background-color': 'var(--sbb-color-cloud-alpha-80)', })} > - + ${image.image} Summary diff --git a/src/elements/flip-card/flip-card-summary/readme.md b/src/elements/flip-card/flip-card-summary/readme.md index 86fac4b926..9063e233e4 100644 --- a/src/elements/flip-card/flip-card-summary/readme.md +++ b/src/elements/flip-card/flip-card-summary/readme.md @@ -5,7 +5,7 @@ The component's slot is implicitly set to `"summary"`. Card Title - + ``` diff --git a/src/elements/flip-card/flip-card/__snapshots__/flip-card.snapshot.spec.snap.js b/src/elements/flip-card/flip-card/__snapshots__/flip-card.snapshot.spec.snap.js index 2551b0c702..4d4aab85a0 100644 --- a/src/elements/flip-card/flip-card/__snapshots__/flip-card.snapshot.spec.snap.js +++ b/src/elements/flip-card/flip-card/__snapshots__/flip-card.snapshot.spec.snap.js @@ -40,9 +40,9 @@ snapshots["sbb-flip-card DOM"] = Summary @@ -74,27 +74,27 @@ snapshots["sbb-flip-card DOM"] = snapshots["sbb-flip-card Shadow DOM"] = `
- - + + - - +
`; /* end snapshot sbb-flip-card Shadow DOM */ @@ -105,18 +105,14 @@ snapshots["sbb-flip-card A11y tree Chrome"] = "role": "WebArea", "name": "", "children": [ - { - "role": "heading", - "name": "Summary", - "level": 4 - }, { "role": "button", - "name": "Click on this card for details" + "name": "Summary, Click on this card for details" }, { - "role": "button", - "name": "" + "role": "heading", + "name": "Summary", + "level": 4 } ] } @@ -130,18 +126,14 @@ snapshots["sbb-flip-card A11y tree Firefox"] = "role": "document", "name": "", "children": [ - { - "role": "heading", - "name": "Summary", - "level": 4 - }, { "role": "button", - "name": "Click on this card for details" + "name": "Summary, Click on this card for details" }, { - "role": "button", - "name": "" + "role": "heading", + "name": "Summary", + "level": 4 } ] } diff --git a/src/elements/flip-card/flip-card/flip-card.scss b/src/elements/flip-card/flip-card/flip-card.scss index a6b5ca59ea..399525bc32 100644 --- a/src/elements/flip-card/flip-card/flip-card.scss +++ b/src/elements/flip-card/flip-card/flip-card.scss @@ -29,7 +29,9 @@ } :host(:hover) { - --sbb-flip-card-background-color: var(--sbb-color-cloud-alpha-80); + @include sbb.hover-mq($hover: true) { + --sbb-flip-card-background-color: var(--sbb-color-cloud-alpha-80); + } } :host([data-flipped]) { @@ -75,6 +77,24 @@ border-radius: var(--sbb-flip-card-border-radius); transition: var(--sbb-flip-card-summary-transition-duration) ease-out; transition-delay: var(--sbb-flip-card-summary-transition-delay); + cursor: pointer; + + @include sbb.if-forced-colors { + &::after { + content: ''; + border: var(--sbb-border-width-2x) solid CanvasText; + border-radius: var(--sbb-flip-card-border-radius); + position: absolute; + inset: 0; + pointer-events: none; + + :host(:hover) & { + @include sbb.hover-mq($hover: true) { + border-color: Highlight; + } + } + } + } } .sbb-flip-card--toggle-button { @@ -87,13 +107,14 @@ } } -button { +.sbb-flip-card-button { @include sbb.button-reset; - cursor: pointer; position: absolute; inset: 0; + width: 100%; border-radius: var(--sbb-flip-card-border-radius); + cursor: pointer; &:not([data-focus-origin='mouse'], [data-focus-origin='touch']):focus-visible { @include sbb.focus-outline; diff --git a/src/elements/flip-card/flip-card/flip-card.snapshot.spec.ts b/src/elements/flip-card/flip-card/flip-card.snapshot.spec.ts index 715d7bd916..93db8a6c8d 100644 --- a/src/elements/flip-card/flip-card/flip-card.snapshot.spec.ts +++ b/src/elements/flip-card/flip-card/flip-card.snapshot.spec.ts @@ -1,7 +1,6 @@ import { expect } from '@open-wc/testing'; import { html } from 'lit/static-html.js'; -import sampleImages from '../../core/images.js'; import { fixture, testA11yTreeSnapshot } from '../../core/testing/private.js'; import type { SbbFlipCardElement } from './flip-card.js'; @@ -13,23 +12,20 @@ import '../../title.js'; import '../../image.js'; import '../../link.js'; +const imageUrl = import.meta.resolve('../../core/testing/assets/placeholder-image.png'); + describe(`sbb-flip-card`, () => { let element: SbbFlipCardElement; beforeEach(async () => { element = await fixture(html` - + Summary - + - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam luctus ornare condimentum. + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam luctus ornare condimentum. Vivamus turpis elit, dapibus eget fringilla pellentesque, lobortis in nibh. Duis dapibus vitae tortor ullamcorper maximus. In convallis consectetur felis. Link diff --git a/src/elements/flip-card/flip-card/flip-card.spec.ts b/src/elements/flip-card/flip-card/flip-card.spec.ts index b95dec7faf..12d8ccc81c 100644 --- a/src/elements/flip-card/flip-card/flip-card.spec.ts +++ b/src/elements/flip-card/flip-card/flip-card.spec.ts @@ -11,17 +11,20 @@ import { SbbFlipCardElement } from './flip-card.js'; import '../flip-card-summary.js'; import '../flip-card-details.js'; import '../../title.js'; +import '../../link/link.js'; describe('sbb-flip-card', () => { let element: SbbFlipCardElement; beforeEach(async () => { element = await fixture( - html` - - Card Title + html` + + Card Title - Some additional text. + + Some additional text. Link + `, ); }); @@ -30,10 +33,10 @@ describe('sbb-flip-card', () => { assert.instanceOf(element, SbbFlipCardElement); }); - it('it toggles on click', async () => { + it('should toggle on click', async () => { const flipSpy = new EventSpy(SbbFlipCardElement.events.flip); - const summary: SbbFlipCardSummaryElement = element.summary; - const details: SbbFlipCardDetailsElement = element.details; + const summary: SbbFlipCardSummaryElement = element.summary!; + const details: SbbFlipCardDetailsElement = element.details!; expect(summary.inert).to.be.equal(false); expect(details.inert).to.be.equal(true); @@ -52,10 +55,32 @@ describe('sbb-flip-card', () => { expect(details.inert).to.be.equal(false); }); - it('it toggles programmatically', async () => { + it('should toggle on host click', async () => { const flipSpy = new EventSpy(SbbFlipCardElement.events.flip); - const summary: SbbFlipCardSummaryElement = element.summary; - const details: SbbFlipCardDetailsElement = element.details; + const summary: SbbFlipCardSummaryElement = element.summary!; + const details: SbbFlipCardDetailsElement = element.details!; + + expect(summary.inert).to.be.equal(false); + expect(details.inert).to.be.equal(true); + expect(element.isFlipped).to.be.false; + + element.click(); + await waitForLitRender(element); + + await waitForCondition(() => flipSpy.events.length === 1); + expect(flipSpy.count).to.be.equal(1); + + expect(element).to.have.attribute('data-flipped'); + expect(element.isFlipped).to.be.true; + + expect(summary.inert).to.be.equal(true); + expect(details.inert).to.be.equal(false); + }); + + it('should toggle programmatically', async () => { + const flipSpy = new EventSpy(SbbFlipCardElement.events.flip); + const summary: SbbFlipCardSummaryElement = element.summary!; + const details: SbbFlipCardDetailsElement = element.details!; expect(summary.inert).to.be.equal(false); expect(details.inert).to.be.equal(true); @@ -73,4 +98,40 @@ describe('sbb-flip-card', () => { expect(summary.inert).to.be.equal(true); expect(details.inert).to.be.equal(false); }); + + it('should set accessibility-label from summary', async () => { + await waitForLitRender(element); + + expect(element.shadowRoot!.querySelector('sbb-screen-reader-only')!.textContent).to.be.equal( + 'Card Title, Click on this card for details', + ); + }); + + it('should prefer accessibility-label', async () => { + element.accessibilityLabel = 'A11Y-Label'; + await waitForLitRender(element); + + expect(element.shadowRoot!.querySelector('sbb-screen-reader-only')!.textContent).to.be.equal( + 'A11Y-Label, Click on this card for details', + ); + }); + + it('should present closing accessibility-label', async () => { + element.toggle(); + await waitForLitRender(element); + + expect(element.shadowRoot!.querySelector('sbb-screen-reader-only')!.textContent).to.be.equal( + 'Click on this card to go back to the summary', + ); + }); + + it('should not close on interactive element click', async () => { + element.toggle(); + await waitForLitRender(element); + + element.querySelector('sbb-link')!.click(); + await waitForLitRender(element); + + expect(element.isFlipped).to.be.true; + }); }); diff --git a/src/elements/flip-card/flip-card/flip-card.ssr.spec.ts b/src/elements/flip-card/flip-card/flip-card.ssr.spec.ts index 4400574e7e..adb0bc458f 100644 --- a/src/elements/flip-card/flip-card/flip-card.ssr.spec.ts +++ b/src/elements/flip-card/flip-card/flip-card.ssr.spec.ts @@ -5,13 +5,44 @@ import { ssrHydratedFixture } from '../../core/testing/private.js'; import { SbbFlipCardElement } from './flip-card.js'; +import '../flip-card-details.js'; +import '../flip-card-summary.js'; +import '../../title.js'; +import '../../image.js'; +import '../../link.js'; + +const imageUrl = import.meta.resolve('../../core/testing/assets/placeholder-image.png'); + describe(`sbb-flip-card ssr`, () => { let root: SbbFlipCardElement; beforeEach(async () => { - root = await ssrHydratedFixture(html``, { - modules: ['./flip-card.js'], - }); + root = await ssrHydratedFixture( + html` + + + Summary + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam luctus ornare condimentum. + Vivamus turpis elit, dapibus eget fringilla pellentesque, lobortis in nibh. Duis dapibus + vitae tortor ullamcorper maximus. In convallis consectetur felis. + Link + + + `, + { + modules: [ + './flip-card.js', + '../flip-card-summary.js', + '../flip-card-details.js', + '../../title.js', + '../../image.js', + '../../link.js', + ], + }, + ); }); it('renders', () => { diff --git a/src/elements/flip-card/flip-card/flip-card.stories.ts b/src/elements/flip-card/flip-card/flip-card.stories.ts index dc2b1ec1d5..3062040609 100644 --- a/src/elements/flip-card/flip-card/flip-card.stories.ts +++ b/src/elements/flip-card/flip-card/flip-card.stories.ts @@ -25,50 +25,74 @@ const imageAlignment: InputType = { }, }; +const label: InputType = { + control: { + type: 'text', + }, + table: { + category: 'Summary', + }, +}; + +const accessibilityLabel: InputType = { + control: { + type: 'text', + }, +}; + const defaultArgTypes: ArgTypes = { imageAlignment, + label, + 'accessibility-label': accessibilityLabel, }; const defaultArgs: Args = { imageAlignment: imageAlignment.options![0], + label: 'Summary', + 'accessibility-label': undefined, }; -const cardSummary = (imageAlignment: any, showImage: boolean): TemplateResult => html` - - Summary +const cardSummary = ( + label: string, + imageAlignment: any, + showImage: boolean, +): TemplateResult => html` + + ${label} ${showImage ? html`` : nothing} `; const cardDetails = (): TemplateResult => html` - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam luctus ornare condimentum. Vivamus + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam luctus ornare condimentum. Vivamus turpis elit, dapibus eget fringilla pellentesque, lobortis in nibh. Duis dapibus vitae tortor ullamcorper maximus. In convallis consectetur felis. - Link + Link + `; const DefaultTemplate = (args: Args): TemplateResult => - html` ${cardSummary(args.imageAlignment, true)} ${cardDetails()} `; + html` + ${cardSummary(args.label, args.imageAlignment, true)} ${cardDetails()} + `; const NoImageTemplate = (args: Args): TemplateResult => - html` - ${cardSummary(args.imageAlignment, false)} ${cardDetails()} + html` + ${cardSummary(args.label, args.imageAlignment, false)} ${cardDetails()} `; const LongContentTemplate = (args: Args): TemplateResult => - html` - ${cardSummary(args.imageAlignment, true)} - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam luctus ornare condimentum. + html` + ${cardSummary(args.label, args.imageAlignment, true)} + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam luctus ornare condimentum. Vivamus turpis elit, dapibus eget fringilla pellentesque, lobortis in nibh. Duis dapibus vitae tortor ullamcorper maximus. In convallis consectetur felis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam luctus ornare condimentum. Vivamus turpis elit, dapibus eget @@ -79,24 +103,8 @@ const LongContentTemplate = (args: Args): TemplateResult => ipsum dolor sit amet, consectetur adipiscing elit. Nam luctus ornare condimentum. Vivamus turpis elit, dapibus eget fringilla pellentesque, lobortis in nibh. Duis dapibus vitae tortor ullamcorper maximus. In convallis consectetur felis. - Link - `; - -const LongTitleTemplate = (args: Args): TemplateResult => - html` - - This is a very long title that should break into multiple lines - - - ${cardDetails()} + Link + `; export const ImageAfter: StoryObj = { @@ -124,9 +132,12 @@ export const LongContent: StoryObj = { }; export const LongTitle: StoryObj = { - render: LongTitleTemplate, + render: DefaultTemplate, argTypes: defaultArgTypes, - args: { ...defaultArgs }, + args: { + ...defaultArgs, + label: 'This is a very long title that should break into multiple lines', + }, }; const meta: Meta = { diff --git a/src/elements/flip-card/flip-card/flip-card.ts b/src/elements/flip-card/flip-card/flip-card.ts index b301768cd9..cfcac275a5 100644 --- a/src/elements/flip-card/flip-card/flip-card.ts +++ b/src/elements/flip-card/flip-card/flip-card.ts @@ -1,8 +1,9 @@ -import type { CSSResultGroup, TemplateResult } from 'lit'; -import { html, LitElement } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; +import { type CSSResultGroup, html, isServer, LitElement, type TemplateResult } from 'lit'; +import { customElement, property, state } from 'lit/decorators.js'; +import { until } from 'lit/directives/until.js'; -import { SbbLanguageController } from '../../core/controllers.js'; +import { IS_FOCUSABLE_QUERY } from '../../core/a11y.js'; +import { SbbConnectedAbortController, SbbLanguageController } from '../../core/controllers.js'; import { EventEmitter } from '../../core/eventing.js'; import { i18nFlipCard, i18nReverseCard } from '../../core/i18n.js'; import { SbbHydrationMixin } from '../../core/mixins.js'; @@ -11,13 +12,13 @@ import type { SbbFlipCardSummaryElement } from '../flip-card-summary.js'; import style from './flip-card.scss?lit&inline'; -import '../../button/secondary-button.js'; +import '../../button/secondary-button-static.js'; +import '../../screen-reader-only.js'; /** - * Displays an informative card that reveals more informations upon being clicked. + * Displays an informative card that reveals more information upon being clicked. * - * @slot summary - Use this slot to provide a sbb-flip-card-summary component. - * @slot details - Use this slot to provide a sbb-flip-card-details component. + * @slot - Use the unnamed slot to add a `sbb-flip-card-summary` and a `sbb-flip-card-details` element. * @event {CustomEvent} flip - Emits when the flip card flips. * */ @@ -28,17 +29,23 @@ export class SbbFlipCardElement extends SbbHydrationMixin(LitElement) { flip: 'flip', } as const; + /** + * This will be forwarded as aria-label to the action in the non flipped state. + * If not set, the textContent of the `sbb-flip-card-summary` is taken. + */ + @property({ attribute: 'accessibility-label' }) public accessibilityLabel: string | undefined; + /** Emits whenever the component is flipped. */ protected flip: EventEmitter = new EventEmitter(this, SbbFlipCardElement.events.flip); /** Returns the slotted sbb-flip-card-summary. */ - public get summary(): SbbFlipCardSummaryElement { - return this.querySelector('sbb-flip-card-summary')!; + public get summary(): SbbFlipCardSummaryElement | null { + return this.querySelector?.('sbb-flip-card-summary'); } /** Returns the slotted sbb-flip-card-details. */ - public get details(): SbbFlipCardDetailsElement { - return this.querySelector('sbb-flip-card-details')!; + public get details(): SbbFlipCardDetailsElement | null { + return this.querySelector?.('sbb-flip-card-details'); } /** Whether the flip card is flipped. */ @@ -49,35 +56,58 @@ export class SbbFlipCardElement extends SbbHydrationMixin(LitElement) { /** Whether the card is flipped or not. */ @state() private _flipped = false; + private _abort = new SbbConnectedAbortController(this); private _language = new SbbLanguageController(this); + public override connectedCallback(): void { + super.connectedCallback(); + this.addEventListener( + 'click', + (event: Event) => { + if ( + event.target === this || + !(event.target as HTMLElement)?.matches?.(IS_FOCUSABLE_QUERY) + ) { + this.toggle(); + } + }, + { signal: this._abort.signal }, + ); + } + /** Toggles the state of the sbb-flip-card. */ public toggle(): void { this._flipped = !this._flipped; this.toggleAttribute('data-flipped', this._flipped); - this.summary.inert = this._flipped; - this.details.inert = !this._flipped; + this.summary!.inert = this._flipped; + this.details!.inert = !this._flipped; this.flip.emit(); } + private async _accessibilityLabel(): Promise { + if (isServer) { + return ''; + } + await this.hydrationComplete; + + return !this._flipped + ? `${(this.accessibilityLabel ? this.accessibilityLabel : this.summary?.textContent?.trim()) ?? ''}, ${i18nFlipCard[this._language.current]}` + : i18nReverseCard[this._language.current]; + } + protected override render(): TemplateResult { return html`
- (this.summary.inert = this._flipped)}> - - (this.details.inert = !this._flipped)}> - + ${until(this._accessibilityLabel(), '')} + + (this.summary!.inert = this._flipped)}> + (this.details!.inert = !this._flipped)}> + this.toggle()} size="s" - > + >
`; } diff --git a/src/elements/flip-card/flip-card/flip-card.visual.spec.ts b/src/elements/flip-card/flip-card/flip-card.visual.spec.ts index 37d1c82050..48f968a68c 100644 --- a/src/elements/flip-card/flip-card/flip-card.visual.spec.ts +++ b/src/elements/flip-card/flip-card/flip-card.visual.spec.ts @@ -4,15 +4,17 @@ import { describeViewports, visualDiffDefault, visualDiffFocus, + visualDiffHover, } from '../../core/testing/private.js'; import { waitForImageReady } from '../../core/testing/wait-for-image-ready.js'; +import type { SbbFlipCardImageAlignment } from '../flip-card-summary.js'; + import './flip-card.js'; import '../flip-card-summary.js'; import '../flip-card-details.js'; import '../../title.js'; import '../../link.js'; import '../../image.js'; -import type { SbbFlipCardImageAlignment } from '../flip-card-summary.js'; const imageUrl = import.meta.resolve('../../core/testing/assets/placeholder-image.png'); @@ -21,16 +23,11 @@ const content = ( imageAlignment: SbbFlipCardImageAlignment = 'after', longContent: boolean = false, ): TemplateResult => - html` + html` ${title} - + - + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam luctus ornare condimentum. Vivamus turpis elit, dapibus eget fringilla pellentesque, lobortis in nibh. ${longContent @@ -49,7 +46,7 @@ describe(`sbb-flip-card`, () => { describeViewports({ viewports: ['zero', 'medium'] }, () => { for (const imageAlignment of ['after', 'below']) { describe(`image-alignment=${imageAlignment}`, () => { - for (const state of [visualDiffDefault, visualDiffFocus]) { + for (const state of [visualDiffDefault, visualDiffHover, visualDiffFocus]) { it( state.name, state.with(async (setup) => { @@ -101,5 +98,20 @@ describe(`sbb-flip-card`, () => { }), ); } + + describe('forcedColors=true', () => { + for (const state of [visualDiffDefault, visualDiffHover, visualDiffFocus]) { + it( + state.name, + state.with(async (setup) => { + await setup.withFixture(html`${content('Summary')}`, { + forcedColors: true, + }); + + await waitForImageReady(setup.snapshotElement.querySelector('sbb-image')!); + }), + ); + } + }); }); }); diff --git a/src/elements/flip-card/flip-card/readme.md b/src/elements/flip-card/flip-card/readme.md index 2da83a0ba4..41e986a2a7 100644 --- a/src/elements/flip-card/flip-card/readme.md +++ b/src/elements/flip-card/flip-card/readme.md @@ -5,7 +5,7 @@ It's meant to be used together with [sbb-flip-card-summary](/docs/elements-sbb-f Card Title - + Some additional text. @@ -23,11 +23,12 @@ The `sbb-flip-card` will switch to the flipped state after the user clicks on it ## Properties -| Name | Attribute | Privacy | Type | Default | Description | -| ----------- | --------- | ------- | --------------------------- | ------- | ------------------------------------------ | -| `details` | - | public | `SbbFlipCardDetailsElement` | | Returns the slotted sbb-flip-card-details. | -| `isFlipped` | - | public | `boolean` | | Whether the flip card is flipped. | -| `summary` | - | public | `SbbFlipCardSummaryElement` | | Returns the slotted sbb-flip-card-summary. | +| Name | Attribute | Privacy | Type | Default | Description | +| -------------------- | --------------------- | ------- | ----------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `accessibilityLabel` | `accessibility-label` | public | `string \| undefined` | | This will be forwarded as aria-label to the action in the non flipped state. If not set, the textContent of the `sbb-flip-card-summary` is taken. | +| `details` | - | public | `SbbFlipCardDetailsElement \| null` | | Returns the slotted sbb-flip-card-details. | +| `isFlipped` | - | public | `boolean` | | Whether the flip card is flipped. | +| `summary` | - | public | `SbbFlipCardSummaryElement \| null` | | Returns the slotted sbb-flip-card-summary. | ## Methods @@ -43,7 +44,6 @@ The `sbb-flip-card` will switch to the flipped state after the user clicks on it ## Slots -| Name | Description | -| --------- | ----------------------------------------------------------- | -| `details` | Use this slot to provide a sbb-flip-card-details component. | -| `summary` | Use this slot to provide a sbb-flip-card-summary component. | +| Name | Description | +| ---- | -------------------------------------------------------------------------------------------- | +| | Use the unnamed slot to add a `sbb-flip-card-summary` and a `sbb-flip-card-details` element. |