From ecf02d5bd5d2e7131b3e24a490df7ee87527df6c Mon Sep 17 00:00:00 2001 From: matthiashader <144090716+matthiashader@users.noreply.github.com> Date: Tue, 22 Oct 2024 16:50:12 +0200 Subject: [PATCH] fix(core/button): fix keyboard navigation & accessibility (#1519) --- .changeset/nasty-mangos-love.md | 5 +++ packages/core/component-doc.json | 8 ++++- .../core/src/components/button/button.tsx | 17 ++++++++-- .../components/date-picker/date-picker.tsx | 19 ++++++++++-- .../date-picker/test/date-picker.ct.ts | 31 +++++++++++++++++++ 5 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 .changeset/nasty-mangos-love.md diff --git a/.changeset/nasty-mangos-love.md b/.changeset/nasty-mangos-love.md new file mode 100644 index 00000000000..f8632ceafac --- /dev/null +++ b/.changeset/nasty-mangos-love.md @@ -0,0 +1,5 @@ +--- +'@siemens/ix': patch +--- + +fix(core/button): fix keyboard navigation & accessibility diff --git a/packages/core/component-doc.json b/packages/core/component-doc.json index 3921c1accba..87755143ae3 100644 --- a/packages/core/component-doc.json +++ b/packages/core/component-doc.json @@ -1533,7 +1533,13 @@ "styles": [], "slots": [], "parts": [], - "listeners": [] + "listeners": [ + { + "event": "click", + "capture": true, + "passive": false + } + ] }, { "dirPath": "src/components/card", diff --git a/packages/core/src/components/button/button.tsx b/packages/core/src/components/button/button.tsx index 3e78601326f..005c91e53e4 100644 --- a/packages/core/src/components/button/button.tsx +++ b/packages/core/src/components/button/button.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, Element, h, Host, Listen, Prop } from '@stencil/core'; import { BaseButton, BaseButtonProps } from './base-button'; export type ButtonVariant = 'danger' | 'primary' | 'secondary'; @@ -69,6 +69,14 @@ export class Button { */ submitButtonElement?: HTMLButtonElement; + @Listen('click', { capture: true }) + handleClick(event: Event) { + if (this.disabled || this.loading) { + event.stopPropagation(); + event.preventDefault(); + } + } + componentDidLoad() { if (this.type === 'submit') { const submitButton = document.createElement('button'); @@ -82,7 +90,12 @@ export class Button { } dispatchFormEvents() { - if (this.type === 'submit' && this.submitButtonElement) { + if ( + this.type === 'submit' && + this.submitButtonElement && + !this.disabled && + !this.loading + ) { this.submitButtonElement.click(); } } diff --git a/packages/core/src/components/date-picker/date-picker.tsx b/packages/core/src/components/date-picker/date-picker.tsx index 74933790d14..24c145d8144 100644 --- a/packages/core/src/components/date-picker/date-picker.tsx +++ b/packages/core/src/components/date-picker/date-picker.tsx @@ -147,6 +147,7 @@ export class DatePicker { * @since 2.1.0 */ @Prop() locale: string = undefined; + @Watch('locale') onLocaleChange() { this.setTranslations(); @@ -518,7 +519,11 @@ export class DatePicker { } } - private selectDay(selectedDay: number) { + private selectDay(selectedDay: number, target: Element) { + if (target.classList.contains('disabled')) { + return; + } + const date = DateTime.fromJSDate( new Date(this.selectedYear, this.selectedMonth, selectedDay) ); @@ -781,8 +786,16 @@ export class DatePicker { id={`day-cell-${day}`} date-calender-day class={this.getDayClasses(day)} - onClick={() => this.selectDay(day)} - onKeyUp={(e) => e.key === 'Enter' && this.selectDay(day)} + onClick={(e) => { + const target = e.currentTarget as HTMLElement; + this.selectDay(day, target); + }} + onKeyUp={(e) => { + const target = e.currentTarget as HTMLElement; + if (e.key === 'Enter') { + this.selectDay(day, target); + } + }} tabIndex={day === this.focusedDay ? 0 : -1} onFocus={() => this.onDayFocus()} onBlur={() => this.onDayBlur()} diff --git a/packages/core/src/components/date-picker/test/date-picker.ct.ts b/packages/core/src/components/date-picker/test/date-picker.ct.ts index 95f359bef7e..31e6315d83b 100644 --- a/packages/core/src/components/date-picker/test/date-picker.ct.ts +++ b/packages/core/src/components/date-picker/test/date-picker.ct.ts @@ -36,6 +36,37 @@ test('translation', async ({ mount, page }) => { await expect(header).toHaveCount(1); }); +test.describe('date picker tests single', () => { + test.beforeEach(async ({ mount }) => { + await mount( + `` + ); + }); + + test('select disabled date with enter', async ({ page }) => { + await page.waitForSelector('ix-date-time-card'); + + await page.getByText(/^9$/).focus(); + await page.keyboard.press('Enter'); + + expect((await getDateObj(page))[0]).toEqual({ + from: '2024/10/10', + to: undefined, + }); + }); + + test('select disabled date with click', async ({ page }) => { + await page.waitForSelector('ix-date-time-card'); + + await page.getByText(/^9$/).click({ force: true }); + + expect((await getDateObj(page))[0]).toEqual({ + from: '2024/10/10', + to: undefined, + }); + }); +}); + test.describe('date picker tests single', () => { test.beforeEach(async ({ mount }) => { await mount(