From 5aa12a3e6d03cac74b748aca6b3e0ec2e10ef31c Mon Sep 17 00:00:00 2001 From: lakshmi-priya-b Date: Fri, 12 Jun 2026 15:53:06 +0000 Subject: [PATCH 1/4] fix(action-card): make action card focusable and keyboard activatable --- .../components/action-card/action-card.scss | 7 +++++ .../components/action-card/action-card.tsx | 26 +++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/packages/core/src/components/action-card/action-card.scss b/packages/core/src/components/action-card/action-card.scss index 4a22a1bff17..a4489939eaf 100644 --- a/packages/core/src/components/action-card/action-card.scss +++ b/packages/core/src/components/action-card/action-card.scss @@ -26,3 +26,10 @@ height: 100%; } } + +:host(:focus-visible) { + outline: var(--theme-focus-border-thickness) solid + var(--theme-color-focus-bdr); + outline-offset: var(--theme-focus-outline-offset); + border-radius: var(--theme-card--border-radius); +} diff --git a/packages/core/src/components/action-card/action-card.tsx b/packages/core/src/components/action-card/action-card.tsx index 775f3acf987..58f17c487e7 100644 --- a/packages/core/src/components/action-card/action-card.tsx +++ b/packages/core/src/components/action-card/action-card.tsx @@ -7,7 +7,7 @@ * LICENSE file in the root directory of this source tree. */ -import { Component, h, Host, Prop } from '@stencil/core'; +import { Component, Element, h, Host, Prop } from '@stencil/core'; import type { ActionCardVariant } from './action-card.types'; import { a11yBoolean, getFallbackLabelFromIconName } from '../utils/a11y'; @@ -17,6 +17,8 @@ import { a11yBoolean, getFallbackLabelFromIconName } from '../utils/a11y'; shadow: true, }) export class IxActionCard { + @Element() hostElement!: HTMLIxActionCardElement; + /** * Card variant */ @@ -61,6 +63,17 @@ export class IxActionCard { */ @Prop() passive: boolean = false; + private onKeyDown(event: KeyboardEvent) { + if (this.passive) { + return; + } + + if (event.key === 'Enter' || event.key === ' ') { + event.preventDefault(); + this.hostElement.click(); + } + } + private getSubheadingTextColor() { return this.variant === 'outline' || this.variant === 'filled' ? 'soft' @@ -74,15 +87,18 @@ export class IxActionCard { : undefined; return ( - + this.onKeyDown(event)} + aria-label={this.ariaLabelCard} + aria-labelledby={ariaLabelledBy} + > {this.icon ? ( From ff31bd93578af5635d8e3de26ccf2761928b2f15 Mon Sep 17 00:00:00 2001 From: lakshmi-priya-b Date: Mon, 15 Jun 2026 04:36:43 +0000 Subject: [PATCH 2/4] fix sonarqube issue and add axe tests --- .../components/action-card/action-card.tsx | 9 ++++- .../action-card/test/action-card.ct.ts | 39 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 packages/core/src/components/action-card/test/action-card.ct.ts diff --git a/packages/core/src/components/action-card/action-card.tsx b/packages/core/src/components/action-card/action-card.tsx index 58f17c487e7..5c510ea2c77 100644 --- a/packages/core/src/components/action-card/action-card.tsx +++ b/packages/core/src/components/action-card/action-card.tsx @@ -68,6 +68,10 @@ export class IxActionCard { return; } + if (event.target !== this.hostElement) { + return; + } + if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); this.hostElement.click(); @@ -86,10 +90,11 @@ export class IxActionCard { ? 'ix-action-card-heading' : undefined; + const isInteractive = !this.passive; return ( this.onKeyDown(event)} aria-label={this.ariaLabelCard} aria-labelledby={ariaLabelledBy} diff --git a/packages/core/src/components/action-card/test/action-card.ct.ts b/packages/core/src/components/action-card/test/action-card.ct.ts new file mode 100644 index 00000000000..c6d41d70843 --- /dev/null +++ b/packages/core/src/components/action-card/test/action-card.ct.ts @@ -0,0 +1,39 @@ +/* + * SPDX-FileCopyrightText: 2024 Siemens AG + * + * SPDX-License-Identifier: MIT + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import { expect } from '@playwright/test'; +import { regressionTest } from '@utils/test'; + +regressionTest.describe('accessibility', () => { + regressionTest('default', async ({ mount, makeAxeBuilder }) => { + await mount(` + + `); + + const accessibilityScanResults = await makeAxeBuilder().analyze(); + + expect(accessibilityScanResults.violations).toEqual([]); + }); + + regressionTest('passive', async ({ mount, makeAxeBuilder }) => { + await mount(` + + `); + + const accessibilityScanResults = await makeAxeBuilder().analyze(); + + expect(accessibilityScanResults.violations).toEqual([]); + }); +}); From d4e88e8b1e823a70966f8cd4af54706a3441d01f Mon Sep 17 00:00:00 2001 From: lakshmi-priya-b Date: Sun, 21 Jun 2026 19:26:28 +0000 Subject: [PATCH 3/4] fix(action-card): use native button for interactive cards to improve accessibility --- .../components/action-card/action-card.scss | 31 +++-- .../components/action-card/action-card.tsx | 111 ++++++++---------- 2 files changed, 72 insertions(+), 70 deletions(-) diff --git a/packages/core/src/components/action-card/action-card.scss b/packages/core/src/components/action-card/action-card.scss index a4489939eaf..9ee8faafa80 100644 --- a/packages/core/src/components/action-card/action-card.scss +++ b/packages/core/src/components/action-card/action-card.scss @@ -15,21 +15,38 @@ width: 13.375rem; height: 7.5rem; min-height: 7.5rem; - cursor: pointer; margin: 0.25rem 0; @include component.ix-component; +} + +button.card-button { + all: unset; + display: block; + box-sizing: border-box; + width: 100%; + height: 100%; + cursor: pointer; ix-card { width: 100%; height: 100%; } -} -:host(:focus-visible) { - outline: var(--theme-focus-border-thickness) solid - var(--theme-color-focus-bdr); - outline-offset: var(--theme-focus-outline-offset); - border-radius: var(--theme-card--border-radius); + &:focus-visible { + outline: var(--theme-focus-border-thickness) solid + var(--theme-color-focus-bdr); + outline-offset: var(--theme-focus-outline-offset); + border-radius: var(--theme-card--border-radius); + } + + :host(.passive) & { + pointer-events: none; + cursor: default; + } + + :host(:not(.passive)) &:active ix-card { + background-color: var(--theme-color-ghost--active); + } } diff --git a/packages/core/src/components/action-card/action-card.tsx b/packages/core/src/components/action-card/action-card.tsx index 5c510ea2c77..8efea1924d2 100644 --- a/packages/core/src/components/action-card/action-card.tsx +++ b/packages/core/src/components/action-card/action-card.tsx @@ -7,7 +7,7 @@ * LICENSE file in the root directory of this source tree. */ -import { Component, Element, h, Host, Prop } from '@stencil/core'; +import { Component, h, Host, Prop } from '@stencil/core'; import type { ActionCardVariant } from './action-card.types'; import { a11yBoolean, getFallbackLabelFromIconName } from '../utils/a11y'; @@ -17,8 +17,6 @@ import { a11yBoolean, getFallbackLabelFromIconName } from '../utils/a11y'; shadow: true, }) export class IxActionCard { - @Element() hostElement!: HTMLIxActionCardElement; - /** * Card variant */ @@ -63,21 +61,6 @@ export class IxActionCard { */ @Prop() passive: boolean = false; - private onKeyDown(event: KeyboardEvent) { - if (this.passive) { - return; - } - - if (event.target !== this.hostElement) { - return; - } - - if (event.key === 'Enter' || event.key === ' ') { - event.preventDefault(); - this.hostElement.click(); - } - } - private getSubheadingTextColor() { return this.variant === 'outline' || this.variant === 'filled' ? 'soft' @@ -90,54 +73,56 @@ export class IxActionCard { ? 'ix-action-card-heading' : undefined; - const isInteractive = !this.passive; return ( - this.onKeyDown(event)} - aria-label={this.ariaLabelCard} - aria-labelledby={ariaLabelledBy} - > - + ); } From f1ad16278abc9de7140f4e73f497bf859ac4c333 Mon Sep 17 00:00:00 2001 From: lakshmi-priya-b Date: Mon, 22 Jun 2026 07:00:50 +0000 Subject: [PATCH 4/4] remove aria-pressed attribute from the button --- packages/core/src/components/action-card/action-card.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/components/action-card/action-card.tsx b/packages/core/src/components/action-card/action-card.tsx index 8efea1924d2..3c63415b2b9 100644 --- a/packages/core/src/components/action-card/action-card.tsx +++ b/packages/core/src/components/action-card/action-card.tsx @@ -80,7 +80,6 @@ export class IxActionCard { tabIndex={this.passive ? -1 : 0} aria-label={this.ariaLabelCard} aria-labelledby={ariaLabelledBy} - aria-pressed={a11yBoolean(this.selected)} >