mirror of
https://github.com/material-components/material-web.git
synced 2026-01-09 07:21:09 +08:00
Merge f59b03c43336d3a1c485da9113d47e159b57e04a into 555b0add40685ad2d799e4bccfc4c69812abe207
This commit is contained in:
commit
78fec59126
@ -23,6 +23,11 @@ import {
|
||||
getValidityAnchor,
|
||||
mixinConstraintValidation,
|
||||
} from '../../labs/behaviors/constraint-validation.js';
|
||||
import {
|
||||
hasState,
|
||||
mixinCustomStateSet,
|
||||
toggleState,
|
||||
} from '../../labs/behaviors/custom-state-set.js';
|
||||
import {mixinElementInternals} from '../../labs/behaviors/element-internals.js';
|
||||
import {
|
||||
getFormState,
|
||||
@ -34,7 +39,7 @@ import {CheckboxValidator} from '../../labs/behaviors/validators/checkbox-valida
|
||||
// Separate variable needed for closure.
|
||||
const checkboxBaseClass = mixinDelegatesAria(
|
||||
mixinConstraintValidation(
|
||||
mixinFormAssociated(mixinElementInternals(LitElement)),
|
||||
mixinFormAssociated(mixinCustomStateSet(mixinElementInternals(LitElement))),
|
||||
),
|
||||
);
|
||||
|
||||
@ -59,14 +64,26 @@ export class Checkbox extends checkboxBaseClass {
|
||||
/**
|
||||
* Whether or not the checkbox is selected.
|
||||
*/
|
||||
@property({type: Boolean}) checked = false;
|
||||
@property({type: Boolean})
|
||||
get checked(): boolean {
|
||||
return this[hasState]('checked');
|
||||
}
|
||||
set checked(checked: boolean) {
|
||||
this[toggleState]('checked', checked);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the checkbox is indeterminate.
|
||||
*
|
||||
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#indeterminate_state_checkboxes
|
||||
*/
|
||||
@property({type: Boolean}) indeterminate = false;
|
||||
@property({type: Boolean})
|
||||
get indeterminate(): boolean {
|
||||
return this[hasState]('indeterminate');
|
||||
}
|
||||
set indeterminate(indeterminate: boolean) {
|
||||
this[toggleState]('indeterminate', indeterminate);
|
||||
}
|
||||
|
||||
/**
|
||||
* When true, require the checkbox to be selected when participating in
|
||||
|
||||
@ -152,6 +152,31 @@ describe('checkbox', () => {
|
||||
expect(input.checked).toEqual(true);
|
||||
expect(harness.element.checked).toEqual(true);
|
||||
});
|
||||
|
||||
it('matches :state(checked) when true', async () => {
|
||||
// Arrange
|
||||
const {harness} = await setupTest();
|
||||
|
||||
// Act
|
||||
harness.element.checked = true;
|
||||
await env.waitForStability();
|
||||
|
||||
// Assert
|
||||
expect(harness.element.matches(':state(checked)'))
|
||||
.withContext("element.matches(':state(checked)')")
|
||||
.toBeTrue();
|
||||
});
|
||||
|
||||
it('does not match :state(checked) when false', async () => {
|
||||
// Arrange
|
||||
// Act
|
||||
const {harness} = await setupTest();
|
||||
|
||||
// Assert
|
||||
expect(harness.element.matches(':state(checked)'))
|
||||
.withContext("element.matches(':state(checked)')")
|
||||
.toBeFalse();
|
||||
});
|
||||
});
|
||||
|
||||
describe('indeterminate', () => {
|
||||
@ -169,6 +194,31 @@ describe('checkbox', () => {
|
||||
expect(input.indeterminate).toEqual(false);
|
||||
expect(input.getAttribute('aria-checked')).not.toEqual('mixed');
|
||||
});
|
||||
|
||||
it('matches :state(indeterminate) when true', async () => {
|
||||
// Arrange
|
||||
const {harness} = await setupTest();
|
||||
|
||||
// Act
|
||||
harness.element.indeterminate = true;
|
||||
await env.waitForStability();
|
||||
|
||||
// Assert
|
||||
expect(harness.element.matches(':state(indeterminate)'))
|
||||
.withContext("element.matches(':state(indeterminate)')")
|
||||
.toBeTrue();
|
||||
});
|
||||
|
||||
it('does not match :state(indeterminate) when false', async () => {
|
||||
// Arrange
|
||||
// Act
|
||||
const {harness} = await setupTest();
|
||||
|
||||
// Assert
|
||||
expect(harness.element.matches(':state(indeterminate)'))
|
||||
.withContext("element.matches(':state(indeterminate)')")
|
||||
.toBeFalse();
|
||||
});
|
||||
});
|
||||
|
||||
describe('disabled', () => {
|
||||
@ -186,13 +236,15 @@ describe('checkbox', () => {
|
||||
|
||||
describe('form submission', () => {
|
||||
async function setupFormTest(propsInit: Partial<Checkbox> = {}) {
|
||||
return await setupTest(html` <form>
|
||||
<md-test-checkbox
|
||||
.checked=${propsInit.checked === true}
|
||||
.disabled=${propsInit.disabled === true}
|
||||
.name=${propsInit.name ?? ''}
|
||||
.value=${propsInit.value ?? ''}></md-test-checkbox>
|
||||
</form>`);
|
||||
return await setupTest(
|
||||
html`<form>
|
||||
<md-test-checkbox
|
||||
.checked=${propsInit.checked === true}
|
||||
.disabled=${propsInit.disabled === true}
|
||||
.name=${propsInit.name ?? ''}
|
||||
.value=${propsInit.value ?? ''}></md-test-checkbox>
|
||||
</form>`,
|
||||
);
|
||||
}
|
||||
|
||||
it('does not submit if not checked', async () => {
|
||||
|
||||
@ -208,3 +208,10 @@ Token | Default value
|
||||
<!-- mdformat on(autogenerated might break rendering in catalog) -->
|
||||
|
||||
<!-- auto-generated API docs end -->
|
||||
|
||||
#### States
|
||||
|
||||
| State | Description |
|
||||
| --- | --- |
|
||||
| `:state(checked)` | Matches when the checkbox is checked. |
|
||||
| `:state(indeterminate)` | Matches when the checkbox is indeterminate. |
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user