Skip to content

Commit 5df2633

Browse files
asynclizcopybara-github
authored andcommitted
chore(labs): add helper isDisabled function for pseudo classes
PiperOrigin-RevId: 900894916
1 parent 7d39d6e commit 5df2633

4 files changed

Lines changed: 62 additions & 6 deletions

File tree

labs/gb/components/button/button.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ import {
1414
setupRipple,
1515
} from '@material/web/labs/gb/components/ripple/ripple.js';
1616
import {createClassMapDirective} from '@material/web/labs/gb/components/shared/directives.js';
17-
import {PSEUDO_CLASSES} from '@material/web/labs/gb/components/shared/pseudo-classes.js';
17+
import {
18+
isDisabled,
19+
PSEUDO_CLASSES,
20+
} from '@material/web/labs/gb/components/shared/pseudo-classes.js';
1821
import {type ClassInfo} from 'lit/directives/class-map.js';
1922

2023
/** Button color configuration types. */
@@ -132,9 +135,7 @@ export function setupButton(
132135
// event listeners as well as prevent the default action. This is because
133136
// the underlying element may not actually be `:disabled`, such as an
134137
// anchor tag or a soft-disabled button.
135-
if (
136-
button.matches(`.${BUTTON_CLASSES.disabled},[aria-disabled="true"]`)
137-
) {
138+
if (isDisabled(button)) {
138139
event.stopImmediatePropagation();
139140
event.preventDefault();
140141
return;

labs/gb/components/ripple/ripple.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
*/
66

77
import {createElementDirective} from '@material/web/labs/gb/components/shared/directives.js';
8-
import {PSEUDO_CLASSES} from '@material/web/labs/gb/components/shared/pseudo-classes.js';
8+
import {
9+
PSEUDO_CLASSES,
10+
isDisabled,
11+
} from '@material/web/labs/gb/components/shared/pseudo-classes.js';
912
import {type ClassInfo} from 'lit/directives/class-map.js';
1013

1114
/** Ripple classes. */
@@ -87,7 +90,7 @@ export function setupRipple(
8790
ripple.addEventListener(
8891
'pointerdown',
8992
(event: PointerEvent): void => {
90-
if (ripple.matches(':disabled,.disabled')) return;
93+
if (isDisabled(ripple)) return;
9194

9295
// Set ripple position to the pointer position.
9396
const rect = ripple.getBoundingClientRect();

labs/gb/components/shared/pseudo-classes.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,13 @@ export const PSEUDO_CLASSES = {
2525
indeterminate: 'indeterminate',
2626
invalid: 'invalid',
2727
};
28+
29+
/**
30+
* Returns whether the element is disabled.
31+
*
32+
* @param element The element to check.
33+
* @return true if the element is disabled.
34+
*/
35+
export function isDisabled(element: Element): boolean {
36+
return element.matches('.disabled,:disabled,[disabled],[aria-disabled=true]');
37+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* @license
3+
* Copyright 2026 Google LLC
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
// import 'jasmine'; (google3-only)
8+
9+
import {Environment} from '@material/web/testing/environment.js';
10+
import {html} from 'lit';
11+
import {isDisabled} from './pseudo-classes.js';
12+
13+
describe('pseudo-classes', () => {
14+
const env = new Environment();
15+
16+
describe('isDisabled()', () => {
17+
it('returns true for elements with .disabled class', () => {
18+
const root = env.render(html`<div class="disabled"></div>`);
19+
expect(isDisabled(root.firstElementChild!)).toBeTrue();
20+
});
21+
22+
it('returns true for elements with :disabled pseudo-class', () => {
23+
const root = env.render(html`<button disabled></button>`);
24+
expect(isDisabled(root.firstElementChild!)).toBeTrue();
25+
});
26+
27+
it('returns true for elements with [disabled] attribute', () => {
28+
const root = env.render(html`<div disabled></div>`);
29+
expect(isDisabled(root.firstElementChild!)).toBeTrue();
30+
});
31+
32+
it('returns true for elements with [aria-disabled=true] attribute', () => {
33+
const root = env.render(html`<div aria-disabled="true"></div>`);
34+
expect(isDisabled(root.firstElementChild!)).toBeTrue();
35+
});
36+
37+
it('returns false for non-disabled elements', () => {
38+
const root = env.render(html`<div></div>`);
39+
expect(isDisabled(root.firstElementChild!)).toBeFalse();
40+
});
41+
});
42+
});

0 commit comments

Comments
 (0)