Skip to content

Commit

Permalink
feat: (CXSPA-8024) - Focus issue on remove button at count 2 (#19283)
Browse files Browse the repository at this point in the history
  • Loading branch information
petarmarkov9449 authored Oct 10, 2024
1 parent ec946e9 commit b53ab91
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 9 deletions.
16 changes: 16 additions & 0 deletions feature-libs/cart/base/styles/components/_item-counter.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
-moz-appearance: textfield;
}
}

&.readonly {
button {
display: none;
Expand Down Expand Up @@ -77,8 +78,17 @@
font-weight: var(--cx-font-weight-bold);
}

// TODO: The styles for ":disabled" selector should be deleted when "a11yItemCounterFocus" feature flag has been removed
&:disabled {
color: var(--cx-color-light);
cursor: not-allowed;
}

@include forFeature('a11yItemCounterFocus') {
&[aria-disabled='true'] {
color: var(--cx-color-light);
cursor: not-allowed;
}
}

@include forFeature('a11yImproveContrast') {
Expand All @@ -90,9 +100,15 @@
&:focus {
box-shadow: 0 0 0 0;
}
// TODO: The styles for ":disabled" selector should be deleted when "a11yItemCounterFocus" feature flag has been removed
&:disabled {
color: var(--cx-color-dark);
}
@include forFeature('a11yItemCounterFocus') {
&[aria-disabled='true'] {
color: var(--cx-color-dark);
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,12 @@ export interface FeatureTogglesInterface {
*/
a11ySearchBoxFocusOnEscape?: boolean;

/**
* In `ItemCounterComponenet`, Remove button no longer lose focus after activating when count is 2.
* Add button no longer lose focus after activating when count is `max - 1`.
*/
a11yItemCounterFocus?: boolean;

/**
* In OCC cart requests, it puts parameters of a cart name and cart description
* into a request body, instead of query params.
Expand Down Expand Up @@ -718,6 +724,7 @@ export const defaultFeatureToggles: Required<FeatureTogglesInterface> = {
a11yDialogTriggerRefocus: false,
a11yAddToWishlistFocus: false,
a11ySearchBoxFocusOnEscape: false,
a11yItemCounterFocus: false,
occCartNameAndDescriptionInHttpRequestBody: false,
cmsBottomHeaderSlotUsingFlexStyles: false,
useSiteThemeService: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ if (environment.cpq) {
a11yDialogTriggerRefocus: true,
a11yAddToWishlistFocus: true,
a11ySearchBoxFocusOnEscape: true,
a11yItemCounterFocus: true,
cmsBottomHeaderSlotUsingFlexStyles: true,
useSiteThemeService: false,
enableConsecutiveCharactersPasswordRequirement: true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
<button
*cxFeature="'a11yItemCounterFocus'"
type="button"
(click)="decrement()"
[attr.aria-disabled]="control.disabled || control.value <= min"
[cxFocus]="{ key: 'decrement' }"
attr.aria-label="{{ 'itemCounter.removeOne' | cxTranslate }}"
title="{{ 'itemCounter.removeOne' | cxTranslate }}"
>
-
</button>
<button
*cxFeature="'!a11yItemCounterFocus'"
type="button"
(click)="decrement()"
[disabled]="control.disabled || control.value <= min"
Expand All @@ -23,6 +35,18 @@
attr.aria-label="{{ 'itemCounter.quantity' | cxTranslate }}"
/>
<button
*cxFeature="'a11yItemCounterFocus'"
type="button"
(click)="increment()"
[attr.aria-disabled]="control.disabled || control.value >= max"
[cxFocus]="{ key: 'increment' }"
attr.aria-label="{{ 'itemCounter.addOneMore' | cxTranslate }}"
title="{{ 'itemCounter.addOneMore' | cxTranslate }}"
>
+
</button>
<button
*cxFeature="'!a11yItemCounterFocus'"
type="button"
(click)="increment()"
[disabled]="control.disabled || control.value >= max"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
import { By } from '@angular/platform-browser';
import { RouterTestingModule } from '@angular/router/testing';
import { I18nTestingModule } from '@spartacus/core';
import { MockKeyboardFocusDirective } from '@spartacus/storefront';
import { MockFeatureDirective } from '../../test/mock-feature-directive';
import { ItemCounterComponent } from './item-counter.component';

const form = new UntypedFormGroup({
Expand All @@ -21,7 +23,11 @@ describe('ItemCounterComponent', () => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule, ReactiveFormsModule, I18nTestingModule],
declarations: [ItemCounterComponent],
declarations: [
ItemCounterComponent,
MockFeatureDirective,
MockKeyboardFocusDirective,
],
}).compileComponents();
}));

Expand Down Expand Up @@ -154,7 +160,11 @@ describe('ItemCounterComponent', () => {
const button: DebugElement[] = fixture.debugElement.queryAll(
By.css('button')
);
expect((<HTMLButtonElement>button[1].nativeElement).disabled).toBeFalsy();
expect(
(<HTMLButtonElement>button[1].nativeElement).getAttribute(
'aria-disabled'
)
).toBe('false');
});

it('should disable increase button if max number is reached', () => {
Expand All @@ -165,8 +175,10 @@ describe('ItemCounterComponent', () => {
By.css('button')
);
expect(
(<HTMLButtonElement>button[1].nativeElement).disabled
).toBeTruthy();
(<HTMLButtonElement>button[1].nativeElement).getAttribute(
'aria-disabled'
)
).toBe('true');
});
});

Expand Down Expand Up @@ -201,7 +213,11 @@ describe('ItemCounterComponent', () => {
const button: DebugElement[] = fixture.debugElement.queryAll(
By.css('button')
);
expect((<HTMLButtonElement>button[0].nativeElement).disabled).toBeFalsy();
expect(
(<HTMLButtonElement>button[0].nativeElement).getAttribute(
'aria-disabled'
)
).toBe('false');
});

it('should disable decrease button if min number is reached', () => {
Expand All @@ -212,8 +228,10 @@ describe('ItemCounterComponent', () => {
By.css('button')
);
expect(
(<HTMLButtonElement>button[0].nativeElement).disabled
).toBeTruthy();
(<HTMLButtonElement>button[0].nativeElement).getAttribute(
'aria-disabled'
)
).toBe('true');
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export class ItemCounterComponent implements OnInit, OnDestroy {

constructor() {
useFeatureStyles('a11yVisibleFocusOverflows');
useFeatureStyles('a11yItemCounterFocus');
}

// TODO: (CXSPA-6034) Remove HostListener next major release
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { I18nModule } from '@spartacus/core';
import { FeaturesConfigModule, I18nModule } from '@spartacus/core';
import { KeyboardFocusModule } from '../../../layout/a11y/keyboard-focus/keyboard-focus.module';
import { ItemCounterComponent } from './item-counter.component';

@NgModule({
imports: [CommonModule, ReactiveFormsModule, I18nModule, KeyboardFocusModule],
imports: [
CommonModule,
ReactiveFormsModule,
I18nModule,
KeyboardFocusModule,
FeaturesConfigModule,
],
declarations: [ItemCounterComponent],
exports: [ItemCounterComponent],
})
Expand Down

0 comments on commit b53ab91

Please sign in to comment.