mirror of
https://github.com/bitwarden/browser
synced 2025-12-12 14:23:32 +00:00
[CL-796] unrevert aria disabled buttons (#15924)
* Use aria-disabled for button disabled state * remove import from testing story * use aria-disabled attr on bitLink button * remove unnecessary story attrs * remove disabled attr if on button element * create caprture click util * use caprture click util and fix tests * fix lint errors * fix event type * combine click capture and attr modification * fix lint error. Commit spec changes left out of last commit in error * inject element ref * move aria-disabled styles to common * move disabled logic into util * fix broken async actions stories * fix broken tests asserting disabled attr * have test check for string true vlalue * fix Signal type * fix form-field story import * remove injector left in error * aria-disable icon buttons * update form component css selector to look for aria-disabled buttons * use correct types. pass nativeElement directly * add JSDoc comment for util function * WIP * WIP * inject service in directive * remove console log * remove disabled attr left in error * update comments * remove unnecessary logic * remove :disabled psuedo selector as its apparently not needed * fix event type * coerce disabled attr to boolean * remove duplicate style concat left by conflict resolution * add back buttonStyles default * move reactive logic back to helper * add test to ensure menu button doesn't open when trigger is disabled * remove menu toggle to fix tests * remove disabled menu story * Fix usage of bitLink in verify email component * Update varaible name * no longer pass destroyRef
This commit is contained in:
@@ -34,23 +34,25 @@ describe("Button", () => {
|
||||
expect(buttonDebugElement.nativeElement.disabled).toBeFalsy();
|
||||
});
|
||||
|
||||
it("should be disabled when disabled is true", () => {
|
||||
it("should be aria-disabled and not html attribute disabled when disabled is true", () => {
|
||||
testAppComponent.disabled = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(buttonDebugElement.nativeElement.disabled).toBeTruthy();
|
||||
expect(buttonDebugElement.attributes["aria-disabled"]).toBe("true");
|
||||
expect(buttonDebugElement.nativeElement.disabled).toBeFalsy();
|
||||
// Anchor tags cannot be disabled.
|
||||
});
|
||||
|
||||
it("should be disabled when attribute disabled is true", () => {
|
||||
expect(disabledButtonDebugElement.nativeElement.disabled).toBeTruthy();
|
||||
it("should be aria-disabled not html attribute disabled when attribute disabled is true", () => {
|
||||
fixture.detectChanges();
|
||||
expect(disabledButtonDebugElement.attributes["aria-disabled"]).toBe("true");
|
||||
expect(disabledButtonDebugElement.nativeElement.disabled).toBeFalsy();
|
||||
});
|
||||
|
||||
it("should be disabled when loading is true", () => {
|
||||
testAppComponent.loading = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(buttonDebugElement.nativeElement.disabled).toBeTruthy();
|
||||
expect(buttonDebugElement.attributes["aria-disabled"]).toBe("true");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
import { NgClass } from "@angular/common";
|
||||
import { input, HostBinding, Component, model, computed, booleanAttribute } from "@angular/core";
|
||||
import {
|
||||
input,
|
||||
HostBinding,
|
||||
Component,
|
||||
model,
|
||||
computed,
|
||||
booleanAttribute,
|
||||
inject,
|
||||
ElementRef,
|
||||
} from "@angular/core";
|
||||
import { toObservable, toSignal } from "@angular/core/rxjs-interop";
|
||||
import { debounce, interval } from "rxjs";
|
||||
|
||||
import { AriaDisableDirective } from "../a11y";
|
||||
import { ButtonLikeAbstraction, ButtonType, ButtonSize } from "../shared/button-like.abstraction";
|
||||
import { ariaDisableElement } from "../utils";
|
||||
|
||||
const focusRing = [
|
||||
"focus-visible:tw-ring-2",
|
||||
@@ -50,9 +61,7 @@ const buttonStyles: Record<ButtonType, string[]> = {
|
||||
templateUrl: "button.component.html",
|
||||
providers: [{ provide: ButtonLikeAbstraction, useExisting: ButtonComponent }],
|
||||
imports: [NgClass],
|
||||
host: {
|
||||
"[attr.disabled]": "disabledAttr()",
|
||||
},
|
||||
hostDirectives: [AriaDisableDirective],
|
||||
})
|
||||
export class ButtonComponent implements ButtonLikeAbstraction {
|
||||
@HostBinding("class") get classList() {
|
||||
@@ -72,14 +81,15 @@ export class ButtonComponent implements ButtonLikeAbstraction {
|
||||
.concat(
|
||||
this.showDisabledStyles() || this.disabled()
|
||||
? [
|
||||
"disabled:tw-bg-secondary-300",
|
||||
"disabled:hover:tw-bg-secondary-300",
|
||||
"disabled:tw-border-secondary-300",
|
||||
"disabled:hover:tw-border-secondary-300",
|
||||
"disabled:!tw-text-muted",
|
||||
"disabled:hover:!tw-text-muted",
|
||||
"disabled:tw-cursor-not-allowed",
|
||||
"disabled:hover:tw-no-underline",
|
||||
"aria-disabled:!tw-bg-secondary-300",
|
||||
"hover:tw-bg-secondary-300",
|
||||
"aria-disabled:tw-border-secondary-300",
|
||||
"hover:tw-border-secondary-300",
|
||||
"aria-disabled:!tw-text-muted",
|
||||
"hover:!tw-text-muted",
|
||||
"aria-disabled:tw-cursor-not-allowed",
|
||||
"hover:tw-no-underline",
|
||||
"aria-disabled:tw-pointer-events-none",
|
||||
]
|
||||
: [],
|
||||
)
|
||||
@@ -88,7 +98,7 @@ export class ButtonComponent implements ButtonLikeAbstraction {
|
||||
|
||||
protected disabledAttr = computed(() => {
|
||||
const disabled = this.disabled() != null && this.disabled() !== false;
|
||||
return disabled || this.loading() ? true : null;
|
||||
return disabled || this.loading();
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -128,4 +138,9 @@ export class ButtonComponent implements ButtonLikeAbstraction {
|
||||
);
|
||||
|
||||
disabled = model<boolean>(false);
|
||||
private el = inject(ElementRef<HTMLButtonElement>);
|
||||
|
||||
constructor() {
|
||||
ariaDisableElement(this.el.nativeElement, this.disabledAttr);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user