fix(checkbox-group): add role=list and role=listitem to checkbox-indeterminate and its children
This commit is contained in:
parent
58c3c532c3
commit
9b9e78951f
4 changed files with 466 additions and 404 deletions
5
.changeset/forty-teachers-sleep.md
Normal file
5
.changeset/forty-teachers-sleep.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@lion/ui': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
[checkbox-group] add role="list" and role="listitem" to checkbox-indeterminate and its children
|
||||||
|
|
@ -197,19 +197,34 @@ export class LionCheckboxIndeterminate extends LionCheckbox {
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
_afterTemplate() {
|
_afterTemplate() {
|
||||||
return html`
|
return html`
|
||||||
<div class="choice-field__nested-checkboxes">
|
<div class="choice-field__nested-checkboxes" role="list">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param {Event} ev
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
_onRequestToAddFormElement() {
|
_onRequestToAddFormElement(ev) {
|
||||||
|
if (!(/** @type {HTMLElement} */ (ev.target).hasAttribute('role'))) {
|
||||||
|
/** @type {HTMLElement} */ (ev.target)?.setAttribute('role', 'listitem');
|
||||||
|
}
|
||||||
this._setOwnCheckedState();
|
this._setOwnCheckedState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Event} ev
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
// eslint-disable-next-line class-methods-use-this
|
||||||
|
_onRequestToRemoveFormElement(ev) {
|
||||||
|
if (/** @type {HTMLElement} */ (ev.target).getAttribute('role') === 'listitem') {
|
||||||
|
/** @type {HTMLElement} */ (ev.target)?.removeAttribute('role');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.indeterminate = false;
|
this.indeterminate = false;
|
||||||
|
|
|
||||||
|
|
@ -79,11 +79,10 @@ export function runCheckboxIndeterminateSuite(customConfig) {
|
||||||
// Assert
|
// Assert
|
||||||
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.false;
|
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.false;
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('should be indeterminate if one child is checked', async () => {
|
it('should be indeterminate if one child is checked', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const el = /** @type {LionCheckboxGroup} */ await fixture(html`
|
const el = /** @type {LionCheckboxGroup} */ await fixture(html`
|
||||||
<${groupTag} name="scientists[]">
|
<${groupTag} name="scientists[]">
|
||||||
<${tag} label="Favorite scientists">
|
<${tag} label="Favorite scientists">
|
||||||
<${childTag} label="Archimedes"></${childTag}>
|
<${childTag} label="Archimedes"></${childTag}>
|
||||||
|
|
@ -93,17 +92,17 @@ export function runCheckboxIndeterminateSuite(customConfig) {
|
||||||
</${groupTag}>
|
</${groupTag}>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector(`${cfg.tagString}`)
|
el.querySelector(`${cfg.tagString}`)
|
||||||
);
|
);
|
||||||
// Assert
|
// Assert
|
||||||
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.true;
|
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be checked if all children are checked', async () => {
|
it('should be checked if all children are checked', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const el = /** @type {LionCheckboxGroup} */ (
|
const el = /** @type {LionCheckboxGroup} */ (
|
||||||
await fixture(html`
|
await fixture(html`
|
||||||
<${groupTag} name="scientists[]">
|
<${groupTag} name="scientists[]">
|
||||||
<${tag} label="Favorite scientists">
|
<${tag} label="Favorite scientists">
|
||||||
<${childTag} label="Archimedes" checked></${childTag}>
|
<${childTag} label="Archimedes" checked></${childTag}>
|
||||||
|
|
@ -112,20 +111,20 @@ export function runCheckboxIndeterminateSuite(customConfig) {
|
||||||
</${tag}>
|
</${tag}>
|
||||||
</${groupTag}>
|
</${groupTag}>
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector(`${cfg.tagString}`)
|
el.querySelector(`${cfg.tagString}`)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.false;
|
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.false;
|
||||||
expect(elIndeterminate?.checked).to.be.true;
|
expect(elIndeterminate?.checked).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should become indeterminate if one child is checked', async () => {
|
it('should become indeterminate if one child is checked', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const el = /** @type {LionCheckboxGroup} */ (
|
const el = /** @type {LionCheckboxGroup} */ (
|
||||||
await fixture(html`
|
await fixture(html`
|
||||||
<${groupTag} name="scientists[]">
|
<${groupTag} name="scientists[]">
|
||||||
<${tag} label="Favorite scientists">
|
<${tag} label="Favorite scientists">
|
||||||
<${childTag} label="Archimedes"></${childTag}>
|
<${childTag} label="Archimedes"></${childTag}>
|
||||||
|
|
@ -134,25 +133,25 @@ export function runCheckboxIndeterminateSuite(customConfig) {
|
||||||
</${tag}>
|
</${tag}>
|
||||||
</${groupTag}>
|
</${groupTag}>
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector(`${cfg.tagString}`)
|
el.querySelector(`${cfg.tagString}`)
|
||||||
);
|
);
|
||||||
|
|
||||||
const { _subCheckboxes } = getCheckboxIndeterminateMembers(elIndeterminate);
|
const { _subCheckboxes } = getCheckboxIndeterminateMembers(elIndeterminate);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
_subCheckboxes[0].checked = true;
|
_subCheckboxes[0].checked = true;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.true;
|
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should become checked if all children are checked', async () => {
|
it('should become checked if all children are checked', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const el = /** @type {LionCheckboxGroup} */ (
|
const el = /** @type {LionCheckboxGroup} */ (
|
||||||
await fixture(html`
|
await fixture(html`
|
||||||
<${groupTag} name="scientists[]">
|
<${groupTag} name="scientists[]">
|
||||||
<${tag} label="Favorite scientists">
|
<${tag} label="Favorite scientists">
|
||||||
<${childTag} label="Archimedes"></${childTag}>
|
<${childTag} label="Archimedes"></${childTag}>
|
||||||
|
|
@ -161,27 +160,27 @@ export function runCheckboxIndeterminateSuite(customConfig) {
|
||||||
</${tag}>
|
</${tag}>
|
||||||
</${groupTag}>
|
</${groupTag}>
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector(`${cfg.tagString}`)
|
el.querySelector(`${cfg.tagString}`)
|
||||||
);
|
);
|
||||||
const { _subCheckboxes } = getCheckboxIndeterminateMembers(elIndeterminate);
|
const { _subCheckboxes } = getCheckboxIndeterminateMembers(elIndeterminate);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
_subCheckboxes[0].checked = true;
|
_subCheckboxes[0].checked = true;
|
||||||
_subCheckboxes[1].checked = true;
|
_subCheckboxes[1].checked = true;
|
||||||
_subCheckboxes[2].checked = true;
|
_subCheckboxes[2].checked = true;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.false;
|
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.false;
|
||||||
expect(elIndeterminate?.checked).to.be.true;
|
expect(elIndeterminate?.checked).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should become indeterminate if all children except disabled ones are checked', async () => {
|
it('should become indeterminate if all children except disabled ones are checked', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const el = /** @type {LionCheckboxGroup} */ (
|
const el = /** @type {LionCheckboxGroup} */ (
|
||||||
await fixture(html`
|
await fixture(html`
|
||||||
<${groupTag} name="scientists[]">
|
<${groupTag} name="scientists[]">
|
||||||
<${tag} label="Favorite scientists">
|
<${tag} label="Favorite scientists">
|
||||||
<${childTag} label="Archimedes"></${childTag}>
|
<${childTag} label="Archimedes"></${childTag}>
|
||||||
|
|
@ -190,26 +189,26 @@ export function runCheckboxIndeterminateSuite(customConfig) {
|
||||||
</${tag}>
|
</${tag}>
|
||||||
</${groupTag}>
|
</${groupTag}>
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector(`${cfg.tagString}`)
|
el.querySelector(`${cfg.tagString}`)
|
||||||
);
|
);
|
||||||
const { _subCheckboxes } = getCheckboxIndeterminateMembers(elIndeterminate);
|
const { _subCheckboxes } = getCheckboxIndeterminateMembers(elIndeterminate);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
_subCheckboxes[0].checked = true;
|
_subCheckboxes[0].checked = true;
|
||||||
_subCheckboxes[2].checked = true;
|
_subCheckboxes[2].checked = true;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.true;
|
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.true;
|
||||||
expect(elIndeterminate?.checked).to.be.false;
|
expect(elIndeterminate?.checked).to.be.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should sync all children when parent is checked (from indeterminate to checked)', async () => {
|
it('should sync all children when parent is checked (from indeterminate to checked)', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const el = /** @type {LionCheckboxGroup} */ (
|
const el = /** @type {LionCheckboxGroup} */ (
|
||||||
await fixture(html`
|
await fixture(html`
|
||||||
<${groupTag} name="scientists[]">
|
<${groupTag} name="scientists[]">
|
||||||
<${tag} label="Favorite scientists">
|
<${tag} label="Favorite scientists">
|
||||||
<${childTag} label="Archimedes"></${childTag}>
|
<${childTag} label="Archimedes"></${childTag}>
|
||||||
|
|
@ -218,27 +217,27 @@ export function runCheckboxIndeterminateSuite(customConfig) {
|
||||||
</${tag}>
|
</${tag}>
|
||||||
</${groupTag}>
|
</${groupTag}>
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector(`${cfg.tagString}`)
|
el.querySelector(`${cfg.tagString}`)
|
||||||
);
|
);
|
||||||
const { _subCheckboxes, _inputNode } = getCheckboxIndeterminateMembers(elIndeterminate);
|
const { _subCheckboxes, _inputNode } = getCheckboxIndeterminateMembers(elIndeterminate);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
_inputNode.click();
|
_inputNode.click();
|
||||||
await elIndeterminate.updateComplete;
|
await elIndeterminate.updateComplete;
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(elIndeterminate.hasAttribute('indeterminate')).to.be.false;
|
expect(elIndeterminate.hasAttribute('indeterminate')).to.be.false;
|
||||||
expect(_subCheckboxes[0].hasAttribute('checked')).to.be.true;
|
expect(_subCheckboxes[0].hasAttribute('checked')).to.be.true;
|
||||||
expect(_subCheckboxes[1].hasAttribute('checked')).to.be.true;
|
expect(_subCheckboxes[1].hasAttribute('checked')).to.be.true;
|
||||||
expect(_subCheckboxes[2].hasAttribute('checked')).to.be.true;
|
expect(_subCheckboxes[2].hasAttribute('checked')).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not sync any disabled children when parent is checked (from indeterminate to checked)', async () => {
|
it('should not sync any disabled children when parent is checked (from indeterminate to checked)', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const el = /** @type {LionCheckboxGroup} */ (
|
const el = /** @type {LionCheckboxGroup} */ (
|
||||||
await fixture(html`
|
await fixture(html`
|
||||||
<${groupTag} name="scientists[]">
|
<${groupTag} name="scientists[]">
|
||||||
<${tag} label="Favorite scientists">
|
<${tag} label="Favorite scientists">
|
||||||
<${childTag} label="Archimedes"></${childTag}>
|
<${childTag} label="Archimedes"></${childTag}>
|
||||||
|
|
@ -247,27 +246,27 @@ export function runCheckboxIndeterminateSuite(customConfig) {
|
||||||
</${tag}>
|
</${tag}>
|
||||||
</${groupTag}>
|
</${groupTag}>
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector(`${cfg.tagString}`)
|
el.querySelector(`${cfg.tagString}`)
|
||||||
);
|
);
|
||||||
const { _subCheckboxes, _inputNode } = getCheckboxIndeterminateMembers(elIndeterminate);
|
const { _subCheckboxes, _inputNode } = getCheckboxIndeterminateMembers(elIndeterminate);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
_inputNode.click();
|
_inputNode.click();
|
||||||
await elIndeterminate.updateComplete;
|
await elIndeterminate.updateComplete;
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(elIndeterminate.hasAttribute('indeterminate')).to.be.true;
|
expect(elIndeterminate.hasAttribute('indeterminate')).to.be.true;
|
||||||
expect(_subCheckboxes[0].hasAttribute('checked')).to.be.true;
|
expect(_subCheckboxes[0].hasAttribute('checked')).to.be.true;
|
||||||
expect(_subCheckboxes[1].hasAttribute('checked')).to.be.false;
|
expect(_subCheckboxes[1].hasAttribute('checked')).to.be.false;
|
||||||
expect(_subCheckboxes[2].hasAttribute('checked')).to.be.true;
|
expect(_subCheckboxes[2].hasAttribute('checked')).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remain unchecked when parent is clicked and all children are disabled', async () => {
|
it('should remain unchecked when parent is clicked and all children are disabled', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const el = /** @type {LionCheckboxGroup} */ (
|
const el = /** @type {LionCheckboxGroup} */ (
|
||||||
await fixture(html`
|
await fixture(html`
|
||||||
<${groupTag} name="scientists[]">
|
<${groupTag} name="scientists[]">
|
||||||
<${tag} label="Favorite scientists">
|
<${tag} label="Favorite scientists">
|
||||||
<${childTag} label="Archimedes" disabled></${childTag}>
|
<${childTag} label="Archimedes" disabled></${childTag}>
|
||||||
|
|
@ -276,28 +275,28 @@ export function runCheckboxIndeterminateSuite(customConfig) {
|
||||||
</${tag}>
|
</${tag}>
|
||||||
</${groupTag}>
|
</${groupTag}>
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector(`${cfg.tagString}`)
|
el.querySelector(`${cfg.tagString}`)
|
||||||
);
|
);
|
||||||
const { _subCheckboxes, _inputNode } = getCheckboxIndeterminateMembers(elIndeterminate);
|
const { _subCheckboxes, _inputNode } = getCheckboxIndeterminateMembers(elIndeterminate);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
_inputNode.click();
|
_inputNode.click();
|
||||||
await elIndeterminate.updateComplete;
|
await elIndeterminate.updateComplete;
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(elIndeterminate.hasAttribute('indeterminate')).to.be.false;
|
expect(elIndeterminate.hasAttribute('indeterminate')).to.be.false;
|
||||||
expect(elIndeterminate.hasAttribute('checked')).to.be.false;
|
expect(elIndeterminate.hasAttribute('checked')).to.be.false;
|
||||||
expect(_subCheckboxes[0].hasAttribute('checked')).to.be.false;
|
expect(_subCheckboxes[0].hasAttribute('checked')).to.be.false;
|
||||||
expect(_subCheckboxes[1].hasAttribute('checked')).to.be.false;
|
expect(_subCheckboxes[1].hasAttribute('checked')).to.be.false;
|
||||||
expect(_subCheckboxes[2].hasAttribute('checked')).to.be.false;
|
expect(_subCheckboxes[2].hasAttribute('checked')).to.be.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remain checked when parent is clicked and all children are disabled and checked', async () => {
|
it('should remain checked when parent is clicked and all children are disabled and checked', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const el = /** @type {LionCheckboxGroup} */ (
|
const el = /** @type {LionCheckboxGroup} */ (
|
||||||
await fixture(html`
|
await fixture(html`
|
||||||
<${groupTag} name="scientists[]">
|
<${groupTag} name="scientists[]">
|
||||||
<${tag} label="Favorite scientists">
|
<${tag} label="Favorite scientists">
|
||||||
<${childTag} label="Archimedes" disabled checked></${childTag}>
|
<${childTag} label="Archimedes" disabled checked></${childTag}>
|
||||||
|
|
@ -306,28 +305,28 @@ export function runCheckboxIndeterminateSuite(customConfig) {
|
||||||
</${tag}>
|
</${tag}>
|
||||||
</${groupTag}>
|
</${groupTag}>
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector(`${cfg.tagString}`)
|
el.querySelector(`${cfg.tagString}`)
|
||||||
);
|
);
|
||||||
const { _subCheckboxes, _inputNode } = getCheckboxIndeterminateMembers(elIndeterminate);
|
const { _subCheckboxes, _inputNode } = getCheckboxIndeterminateMembers(elIndeterminate);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
_inputNode.click();
|
_inputNode.click();
|
||||||
await elIndeterminate.updateComplete;
|
await elIndeterminate.updateComplete;
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(elIndeterminate.hasAttribute('indeterminate')).to.be.false;
|
expect(elIndeterminate.hasAttribute('indeterminate')).to.be.false;
|
||||||
expect(elIndeterminate.hasAttribute('checked')).to.be.true;
|
expect(elIndeterminate.hasAttribute('checked')).to.be.true;
|
||||||
expect(_subCheckboxes[0].hasAttribute('checked')).to.be.true;
|
expect(_subCheckboxes[0].hasAttribute('checked')).to.be.true;
|
||||||
expect(_subCheckboxes[1].hasAttribute('checked')).to.be.true;
|
expect(_subCheckboxes[1].hasAttribute('checked')).to.be.true;
|
||||||
expect(_subCheckboxes[2].hasAttribute('checked')).to.be.true;
|
expect(_subCheckboxes[2].hasAttribute('checked')).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should sync all children when parent is checked (from unchecked to checked)', async () => {
|
it('should sync all children when parent is checked (from unchecked to checked)', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const el = /** @type {LionCheckboxGroup} */ (
|
const el = /** @type {LionCheckboxGroup} */ (
|
||||||
await fixture(html`
|
await fixture(html`
|
||||||
<${groupTag} name="scientists[]">
|
<${groupTag} name="scientists[]">
|
||||||
<${tag} label="Favorite scientists">
|
<${tag} label="Favorite scientists">
|
||||||
<${childTag} label="Archimedes"></${childTag}>
|
<${childTag} label="Archimedes"></${childTag}>
|
||||||
|
|
@ -336,27 +335,27 @@ export function runCheckboxIndeterminateSuite(customConfig) {
|
||||||
</${tag}>
|
</${tag}>
|
||||||
</${groupTag}>
|
</${groupTag}>
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector(`${cfg.tagString}`)
|
el.querySelector(`${cfg.tagString}`)
|
||||||
);
|
);
|
||||||
const { _subCheckboxes, _inputNode } = getCheckboxIndeterminateMembers(elIndeterminate);
|
const { _subCheckboxes, _inputNode } = getCheckboxIndeterminateMembers(elIndeterminate);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
_inputNode.click();
|
_inputNode.click();
|
||||||
await elIndeterminate.updateComplete;
|
await elIndeterminate.updateComplete;
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(elIndeterminate.hasAttribute('indeterminate')).to.be.false;
|
expect(elIndeterminate.hasAttribute('indeterminate')).to.be.false;
|
||||||
expect(_subCheckboxes[0].hasAttribute('checked')).to.be.true;
|
expect(_subCheckboxes[0].hasAttribute('checked')).to.be.true;
|
||||||
expect(_subCheckboxes[1].hasAttribute('checked')).to.be.true;
|
expect(_subCheckboxes[1].hasAttribute('checked')).to.be.true;
|
||||||
expect(_subCheckboxes[2].hasAttribute('checked')).to.be.true;
|
expect(_subCheckboxes[2].hasAttribute('checked')).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should sync all children when parent is checked (from checked to unchecked)', async () => {
|
it('should sync all children when parent is checked (from checked to unchecked)', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const el = /** @type {LionCheckboxGroup} */ (
|
const el = /** @type {LionCheckboxGroup} */ (
|
||||||
await fixture(html`
|
await fixture(html`
|
||||||
<${groupTag} name="scientists[]">
|
<${groupTag} name="scientists[]">
|
||||||
<${tag} label="Favorite scientists">
|
<${tag} label="Favorite scientists">
|
||||||
<${childTag} label="Archimedes" checked></${childTag}>
|
<${childTag} label="Archimedes" checked></${childTag}>
|
||||||
|
|
@ -365,27 +364,27 @@ export function runCheckboxIndeterminateSuite(customConfig) {
|
||||||
</${tag}>
|
</${tag}>
|
||||||
</${groupTag}>
|
</${groupTag}>
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector(`${cfg.tagString}`)
|
el.querySelector(`${cfg.tagString}`)
|
||||||
);
|
);
|
||||||
const { _subCheckboxes, _inputNode } = getCheckboxIndeterminateMembers(elIndeterminate);
|
const { _subCheckboxes, _inputNode } = getCheckboxIndeterminateMembers(elIndeterminate);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
_inputNode.click();
|
_inputNode.click();
|
||||||
await elIndeterminate.updateComplete;
|
await elIndeterminate.updateComplete;
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.false;
|
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.false;
|
||||||
expect(_subCheckboxes[0].hasAttribute('checked')).to.be.false;
|
expect(_subCheckboxes[0].hasAttribute('checked')).to.be.false;
|
||||||
expect(_subCheckboxes[1].hasAttribute('checked')).to.be.false;
|
expect(_subCheckboxes[1].hasAttribute('checked')).to.be.false;
|
||||||
expect(_subCheckboxes[2].hasAttribute('checked')).to.be.false;
|
expect(_subCheckboxes[2].hasAttribute('checked')).to.be.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work as expected with siblings checkbox-indeterminate', async () => {
|
it('should work as expected with siblings checkbox-indeterminate', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const el = /** @type {LionCheckboxGroup} */ (
|
const el = /** @type {LionCheckboxGroup} */ (
|
||||||
await fixture(html`
|
await fixture(html`
|
||||||
<${groupTag} name="scientists[]" label="Favorite scientists">
|
<${groupTag} name="scientists[]" label="Favorite scientists">
|
||||||
<${tag}
|
<${tag}
|
||||||
label="Old Greek scientists"
|
label="Old Greek scientists"
|
||||||
|
|
@ -420,38 +419,38 @@ export function runCheckboxIndeterminateSuite(customConfig) {
|
||||||
</${tag}>
|
</${tag}>
|
||||||
</${groupTag}>
|
</${groupTag}>
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
const elFirstIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elFirstIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector('#first-checkbox-indeterminate')
|
el.querySelector('#first-checkbox-indeterminate')
|
||||||
);
|
);
|
||||||
|
|
||||||
const elSecondIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elSecondIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector('#second-checkbox-indeterminate')
|
el.querySelector('#second-checkbox-indeterminate')
|
||||||
);
|
);
|
||||||
|
|
||||||
const elFirstSubCheckboxes = getCheckboxIndeterminateMembers(elFirstIndeterminate);
|
const elFirstSubCheckboxes = getCheckboxIndeterminateMembers(elFirstIndeterminate);
|
||||||
const elSecondSubCheckboxes = getCheckboxIndeterminateMembers(elSecondIndeterminate);
|
const elSecondSubCheckboxes = getCheckboxIndeterminateMembers(elSecondIndeterminate);
|
||||||
|
|
||||||
// Act - check the first sibling
|
// Act - check the first sibling
|
||||||
elFirstSubCheckboxes._inputNode.click();
|
elFirstSubCheckboxes._inputNode.click();
|
||||||
await elFirstIndeterminate.updateComplete;
|
await elFirstIndeterminate.updateComplete;
|
||||||
await elSecondIndeterminate.updateComplete;
|
await elSecondIndeterminate.updateComplete;
|
||||||
|
|
||||||
// Assert - the second sibling should not be affected
|
// Assert - the second sibling should not be affected
|
||||||
|
|
||||||
expect(elFirstIndeterminate.hasAttribute('indeterminate')).to.be.false;
|
expect(elFirstIndeterminate.hasAttribute('indeterminate')).to.be.false;
|
||||||
expect(elFirstSubCheckboxes._subCheckboxes[0].hasAttribute('checked')).to.be.true;
|
expect(elFirstSubCheckboxes._subCheckboxes[0].hasAttribute('checked')).to.be.true;
|
||||||
expect(elFirstSubCheckboxes._subCheckboxes[1].hasAttribute('checked')).to.be.true;
|
expect(elFirstSubCheckboxes._subCheckboxes[1].hasAttribute('checked')).to.be.true;
|
||||||
expect(elFirstSubCheckboxes._subCheckboxes[2].hasAttribute('checked')).to.be.true;
|
expect(elFirstSubCheckboxes._subCheckboxes[2].hasAttribute('checked')).to.be.true;
|
||||||
|
|
||||||
expect(elSecondSubCheckboxes._subCheckboxes[0].hasAttribute('checked')).to.be.false;
|
expect(elSecondSubCheckboxes._subCheckboxes[0].hasAttribute('checked')).to.be.false;
|
||||||
expect(elSecondSubCheckboxes._subCheckboxes[1].hasAttribute('checked')).to.be.false;
|
expect(elSecondSubCheckboxes._subCheckboxes[1].hasAttribute('checked')).to.be.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work as expected with nested indeterminate checkboxes', async () => {
|
it('should work as expected with nested indeterminate checkboxes', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const el = /** @type {LionCheckboxGroup} */ (
|
const el = /** @type {LionCheckboxGroup} */ (
|
||||||
await fixture(html`
|
await fixture(html`
|
||||||
<${groupTag} name="scientists[]" label="Favorite scientists">
|
<${groupTag} name="scientists[]" label="Favorite scientists">
|
||||||
<${tag} label="Scientists" id="parent-checkbox-indeterminate">
|
<${tag} label="Scientists" id="parent-checkbox-indeterminate">
|
||||||
<${childTag}
|
<${childTag}
|
||||||
|
|
@ -484,62 +483,62 @@ export function runCheckboxIndeterminateSuite(customConfig) {
|
||||||
</${tag}>
|
</${tag}>
|
||||||
</${groupTag}>
|
</${groupTag}>
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
const elNestedIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elNestedIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector('#nested-checkbox-indeterminate')
|
el.querySelector('#nested-checkbox-indeterminate')
|
||||||
);
|
);
|
||||||
const elParentIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elParentIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector('#parent-checkbox-indeterminate')
|
el.querySelector('#parent-checkbox-indeterminate')
|
||||||
);
|
);
|
||||||
const elNestedSubCheckboxes = getCheckboxIndeterminateMembers(elNestedIndeterminate);
|
const elNestedSubCheckboxes = getCheckboxIndeterminateMembers(elNestedIndeterminate);
|
||||||
const elParentSubCheckboxes = getCheckboxIndeterminateMembers(elParentIndeterminate);
|
const elParentSubCheckboxes = getCheckboxIndeterminateMembers(elParentIndeterminate);
|
||||||
|
|
||||||
// Act - check a nested checkbox
|
// Act - check a nested checkbox
|
||||||
if (elNestedIndeterminate) {
|
if (elNestedIndeterminate) {
|
||||||
|
// @ts-ignore [allow-protected] in test
|
||||||
|
elNestedSubCheckboxes._subCheckboxes[0]._inputNode.click();
|
||||||
|
}
|
||||||
|
await el.updateComplete;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(elNestedIndeterminate?.hasAttribute('indeterminate')).to.be.true;
|
||||||
|
expect(elParentIndeterminate?.hasAttribute('indeterminate')).to.be.true;
|
||||||
|
|
||||||
|
// Act - check all nested checkbox
|
||||||
// @ts-ignore [allow-protected] in test
|
// @ts-ignore [allow-protected] in test
|
||||||
elNestedSubCheckboxes._subCheckboxes[0]._inputNode.click();
|
if (elNestedIndeterminate) elNestedSubCheckboxes._subCheckboxes[1]._inputNode.click();
|
||||||
}
|
|
||||||
await el.updateComplete;
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(elNestedIndeterminate?.hasAttribute('indeterminate')).to.be.true;
|
|
||||||
expect(elParentIndeterminate?.hasAttribute('indeterminate')).to.be.true;
|
|
||||||
|
|
||||||
// Act - check all nested checkbox
|
|
||||||
// @ts-ignore [allow-protected] in test
|
|
||||||
if (elNestedIndeterminate) elNestedSubCheckboxes._subCheckboxes[1]._inputNode.click();
|
|
||||||
// @ts-ignore [allow-protected] in test
|
|
||||||
if (elNestedIndeterminate) elNestedSubCheckboxes._subCheckboxes[2]._inputNode.click();
|
|
||||||
await el.updateComplete;
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(elNestedIndeterminate?.hasAttribute('checked')).to.be.true;
|
|
||||||
expect(elNestedIndeterminate?.hasAttribute('indeterminate')).to.be.false;
|
|
||||||
expect(elParentIndeterminate?.hasAttribute('checked')).to.be.false;
|
|
||||||
expect(elParentIndeterminate?.hasAttribute('indeterminate')).to.be.true;
|
|
||||||
|
|
||||||
// Act - finally check all remaining checkbox
|
|
||||||
if (elParentIndeterminate) {
|
|
||||||
// @ts-ignore [allow-protected] in test
|
// @ts-ignore [allow-protected] in test
|
||||||
elParentSubCheckboxes._subCheckboxes[0]._inputNode.click();
|
if (elNestedIndeterminate) elNestedSubCheckboxes._subCheckboxes[2]._inputNode.click();
|
||||||
}
|
await el.updateComplete;
|
||||||
if (elParentIndeterminate) {
|
|
||||||
// @ts-ignore [allow-protected] in test
|
|
||||||
elParentSubCheckboxes._subCheckboxes[1]._inputNode.click();
|
|
||||||
}
|
|
||||||
await el.updateComplete;
|
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(elNestedIndeterminate?.hasAttribute('checked')).to.be.true;
|
expect(elNestedIndeterminate?.hasAttribute('checked')).to.be.true;
|
||||||
expect(elNestedIndeterminate?.hasAttribute('indeterminate')).to.be.false;
|
expect(elNestedIndeterminate?.hasAttribute('indeterminate')).to.be.false;
|
||||||
expect(elParentIndeterminate?.hasAttribute('checked')).to.be.true;
|
expect(elParentIndeterminate?.hasAttribute('checked')).to.be.false;
|
||||||
expect(elParentIndeterminate?.hasAttribute('indeterminate')).to.be.false;
|
expect(elParentIndeterminate?.hasAttribute('indeterminate')).to.be.true;
|
||||||
});
|
|
||||||
|
|
||||||
it('should work as expected if extra html', async () => {
|
// Act - finally check all remaining checkbox
|
||||||
// Arrange
|
if (elParentIndeterminate) {
|
||||||
const el = /** @type {LionCheckboxGroup} */ (
|
// @ts-ignore [allow-protected] in test
|
||||||
await fixture(html`
|
elParentSubCheckboxes._subCheckboxes[0]._inputNode.click();
|
||||||
|
}
|
||||||
|
if (elParentIndeterminate) {
|
||||||
|
// @ts-ignore [allow-protected] in test
|
||||||
|
elParentSubCheckboxes._subCheckboxes[1]._inputNode.click();
|
||||||
|
}
|
||||||
|
await el.updateComplete;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(elNestedIndeterminate?.hasAttribute('checked')).to.be.true;
|
||||||
|
expect(elNestedIndeterminate?.hasAttribute('indeterminate')).to.be.false;
|
||||||
|
expect(elParentIndeterminate?.hasAttribute('checked')).to.be.true;
|
||||||
|
expect(elParentIndeterminate?.hasAttribute('indeterminate')).to.be.false;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should work as expected if extra html', async () => {
|
||||||
|
// Arrange
|
||||||
|
const el = /** @type {LionCheckboxGroup} */ (
|
||||||
|
await fixture(html`
|
||||||
<${groupTag} name="scientists[]">
|
<${groupTag} name="scientists[]">
|
||||||
<div>
|
<div>
|
||||||
Let's have some fun
|
Let's have some fun
|
||||||
|
|
@ -555,64 +554,27 @@ export function runCheckboxIndeterminateSuite(customConfig) {
|
||||||
<div>Too much fun, stop it !</div>
|
<div>Too much fun, stop it !</div>
|
||||||
</${groupTag}>
|
</${groupTag}>
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
|
||||||
el.querySelector(`${cfg.tagString}`)
|
|
||||||
);
|
|
||||||
const { _subCheckboxes } = getCheckboxIndeterminateMembers(elIndeterminate);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
_subCheckboxes[0].checked = true;
|
|
||||||
_subCheckboxes[1].checked = true;
|
|
||||||
_subCheckboxes[2].checked = true;
|
|
||||||
await el.updateComplete;
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.false;
|
|
||||||
expect(elIndeterminate?.checked).to.be.true;
|
|
||||||
});
|
|
||||||
|
|
||||||
// https://www.w3.org/TR/wai-aria-practices-1.1/examples/checkbox/checkbox-2/checkbox-2.html
|
|
||||||
describe('mixed-state', () => {
|
|
||||||
it('can have a mixed-state (using mixed-state attribute), none -> indeterminate -> all, cycling through', async () => {
|
|
||||||
const el = await fixture(html`
|
|
||||||
<${groupTag} name="scientists[]">
|
|
||||||
<${tag} mixed-state label="Favorite scientists">
|
|
||||||
<${childTag} label="Archimedes" checked></${childTag}>
|
|
||||||
<${childTag} label="Francis Bacon"></${childTag}>
|
|
||||||
<${childTag} label="Marie Curie"></${childTag}>
|
|
||||||
</${tag}>
|
|
||||||
</${groupTag}>
|
|
||||||
`);
|
|
||||||
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector(`${cfg.tagString}`)
|
el.querySelector(`${cfg.tagString}`)
|
||||||
);
|
);
|
||||||
|
const { _subCheckboxes } = getCheckboxIndeterminateMembers(elIndeterminate);
|
||||||
|
|
||||||
expect(elIndeterminate.mixedState).to.be.true;
|
// Act
|
||||||
expect(elIndeterminate.checked).to.be.false;
|
_subCheckboxes[0].checked = true;
|
||||||
expect(elIndeterminate.indeterminate).to.be.true;
|
_subCheckboxes[1].checked = true;
|
||||||
|
_subCheckboxes[2].checked = true;
|
||||||
|
await el.updateComplete;
|
||||||
|
|
||||||
// @ts-ignore for testing purposes, we access this protected getter
|
// Assert
|
||||||
elIndeterminate._inputNode.click();
|
expect(elIndeterminate?.hasAttribute('indeterminate')).to.be.false;
|
||||||
await elIndeterminate.updateComplete;
|
expect(elIndeterminate?.checked).to.be.true;
|
||||||
expect(elIndeterminate.checked).to.be.true;
|
|
||||||
expect(elIndeterminate.indeterminate).to.be.false;
|
|
||||||
|
|
||||||
// @ts-ignore for testing purposes, we access this protected getter
|
|
||||||
elIndeterminate._inputNode.click();
|
|
||||||
await elIndeterminate.updateComplete;
|
|
||||||
expect(elIndeterminate.checked).to.be.false;
|
|
||||||
expect(elIndeterminate.indeterminate).to.be.false;
|
|
||||||
|
|
||||||
// @ts-ignore for testing purposes, we access this protected getter
|
|
||||||
elIndeterminate._inputNode.click();
|
|
||||||
await elIndeterminate.updateComplete;
|
|
||||||
expect(elIndeterminate.checked).to.be.false;
|
|
||||||
expect(elIndeterminate.indeterminate).to.be.true;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should reset to old child checkbox states when reaching indeterminate state', async () => {
|
// https://www.w3.org/TR/wai-aria-practices-1.1/examples/checkbox/checkbox-2/checkbox-2.html
|
||||||
const el = await fixture(html`
|
describe('mixed-state', () => {
|
||||||
|
it('can have a mixed-state (using mixed-state attribute), none -> indeterminate -> all, cycling through', async () => {
|
||||||
|
const el = await fixture(html`
|
||||||
<${groupTag} name="scientists[]">
|
<${groupTag} name="scientists[]">
|
||||||
<${tag} mixed-state label="Favorite scientists">
|
<${tag} mixed-state label="Favorite scientists">
|
||||||
<${childTag} label="Archimedes" checked></${childTag}>
|
<${childTag} label="Archimedes" checked></${childTag}>
|
||||||
|
|
@ -621,102 +583,179 @@ export function runCheckboxIndeterminateSuite(customConfig) {
|
||||||
</${tag}>
|
</${tag}>
|
||||||
</${groupTag}>
|
</${groupTag}>
|
||||||
`);
|
`);
|
||||||
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
el.querySelector(`${cfg.tagString}`)
|
el.querySelector(`${cfg.tagString}`)
|
||||||
);
|
);
|
||||||
const checkboxEls = /** @type {LionCheckbox[]} */ (
|
|
||||||
Array.from(el.querySelectorAll(`${cfg.childTagString}`))
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(checkboxEls.map(checkboxEl => checkboxEl.checked)).to.eql([true, false, false]);
|
expect(elIndeterminate.mixedState).to.be.true;
|
||||||
|
expect(elIndeterminate.checked).to.be.false;
|
||||||
|
expect(elIndeterminate.indeterminate).to.be.true;
|
||||||
|
|
||||||
// @ts-ignore for testing purposes, we access this protected getter
|
|
||||||
elIndeterminate._inputNode.click();
|
|
||||||
await elIndeterminate.updateComplete;
|
|
||||||
expect(checkboxEls.map(checkboxEl => checkboxEl.checked)).to.eql([true, true, true]);
|
|
||||||
|
|
||||||
// @ts-ignore for testing purposes, we access this protected getter
|
|
||||||
elIndeterminate._inputNode.click();
|
|
||||||
await elIndeterminate.updateComplete;
|
|
||||||
expect(checkboxEls.map(checkboxEl => checkboxEl.checked)).to.eql([false, false, false]);
|
|
||||||
|
|
||||||
// @ts-ignore for testing purposes, we access this protected getter
|
|
||||||
elIndeterminate._inputNode.click();
|
|
||||||
await elIndeterminate.updateComplete;
|
|
||||||
expect(checkboxEls.map(checkboxEl => checkboxEl.checked)).to.eql([true, false, false]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should no longer reach indeterminate state if the child boxes are all checked or all unchecked during indeterminate state', async () => {
|
|
||||||
const el = await fixture(html`
|
|
||||||
<${groupTag} name="scientists[]">
|
|
||||||
<${tag} mixed-state label="Favorite scientists">
|
|
||||||
<${childTag} label="Archimedes" checked></${childTag}>
|
|
||||||
<${childTag} label="Francis Bacon"></${childTag}>
|
|
||||||
<${childTag} label="Marie Curie"></${childTag}>
|
|
||||||
</${tag}>
|
|
||||||
</${groupTag}>
|
|
||||||
`);
|
|
||||||
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
|
||||||
el.querySelector(`${cfg.tagString}`)
|
|
||||||
);
|
|
||||||
const checkboxEls = /** @type {LionCheckbox[]} */ (
|
|
||||||
Array.from(el.querySelectorAll(`${cfg.childTagString}`))
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check when all child boxes in indeterminate state are unchecked
|
|
||||||
// we don't have a tri-state, but a duo-state.
|
|
||||||
|
|
||||||
// @ts-ignore for testing purposes, we access this protected getter
|
|
||||||
checkboxEls[0]._inputNode.click();
|
|
||||||
await elIndeterminate.updateComplete;
|
|
||||||
|
|
||||||
// @ts-ignore for testing purposes, we access this protected getter
|
|
||||||
elIndeterminate._inputNode.click();
|
|
||||||
await elIndeterminate.updateComplete;
|
|
||||||
expect(elIndeterminate.checked).to.be.true;
|
|
||||||
expect(elIndeterminate.indeterminate).to.be.false;
|
|
||||||
|
|
||||||
// @ts-ignore for testing purposes, we access this protected getter
|
|
||||||
elIndeterminate._inputNode.click();
|
|
||||||
await elIndeterminate.updateComplete;
|
|
||||||
expect(elIndeterminate.checked).to.be.false;
|
|
||||||
expect(elIndeterminate.indeterminate).to.be.false;
|
|
||||||
|
|
||||||
// @ts-ignore for testing purposes, we access this protected getter
|
|
||||||
elIndeterminate._inputNode.click();
|
|
||||||
await elIndeterminate.updateComplete;
|
|
||||||
expect(elIndeterminate.checked).to.be.true;
|
|
||||||
expect(elIndeterminate.indeterminate).to.be.false;
|
|
||||||
|
|
||||||
// Check when all child boxes in indeterminate state are getting checked
|
|
||||||
// we also don't have a tri-state, but a duo-state.
|
|
||||||
|
|
||||||
// @ts-ignore for testing purposes, we access this protected getter
|
|
||||||
elIndeterminate._inputNode.click(); // unchecked
|
|
||||||
await elIndeterminate.updateComplete;
|
|
||||||
for (const checkEl of checkboxEls) {
|
|
||||||
// @ts-ignore for testing purposes, we access this protected getter
|
// @ts-ignore for testing purposes, we access this protected getter
|
||||||
checkEl._inputNode.click();
|
elIndeterminate._inputNode.click();
|
||||||
// Give each checking of the sub checkbox a chance to finish updating
|
|
||||||
// This means indeterminate state will be true for a bit and the state gets stored
|
|
||||||
await checkEl.updateComplete;
|
|
||||||
await elIndeterminate.updateComplete;
|
await elIndeterminate.updateComplete;
|
||||||
}
|
expect(elIndeterminate.checked).to.be.true;
|
||||||
|
expect(elIndeterminate.indeterminate).to.be.false;
|
||||||
|
|
||||||
expect(elIndeterminate.checked).to.be.true;
|
// @ts-ignore for testing purposes, we access this protected getter
|
||||||
expect(elIndeterminate.indeterminate).to.be.false;
|
elIndeterminate._inputNode.click();
|
||||||
|
await elIndeterminate.updateComplete;
|
||||||
|
expect(elIndeterminate.checked).to.be.false;
|
||||||
|
expect(elIndeterminate.indeterminate).to.be.false;
|
||||||
|
|
||||||
// @ts-ignore for testing purposes, we access this protected getter
|
// @ts-ignore for testing purposes, we access this protected getter
|
||||||
elIndeterminate._inputNode.click();
|
elIndeterminate._inputNode.click();
|
||||||
await elIndeterminate.updateComplete;
|
await elIndeterminate.updateComplete;
|
||||||
expect(elIndeterminate.checked).to.be.false;
|
expect(elIndeterminate.checked).to.be.false;
|
||||||
expect(elIndeterminate.indeterminate).to.be.false;
|
expect(elIndeterminate.indeterminate).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
// @ts-ignore for testing purposes, we access this protected getter
|
it('should reset to old child checkbox states when reaching indeterminate state', async () => {
|
||||||
elIndeterminate._inputNode.click();
|
const el = await fixture(html`
|
||||||
await elIndeterminate.updateComplete;
|
<${groupTag} name="scientists[]">
|
||||||
expect(elIndeterminate.checked).to.be.true;
|
<${tag} mixed-state label="Favorite scientists">
|
||||||
expect(elIndeterminate.indeterminate).to.be.false;
|
<${childTag} label="Archimedes" checked></${childTag}>
|
||||||
|
<${childTag} label="Francis Bacon"></${childTag}>
|
||||||
|
<${childTag} label="Marie Curie"></${childTag}>
|
||||||
|
</${tag}>
|
||||||
|
</${groupTag}>
|
||||||
|
`);
|
||||||
|
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
|
el.querySelector(`${cfg.tagString}`)
|
||||||
|
);
|
||||||
|
const checkboxEls = /** @type {LionCheckbox[]} */ (
|
||||||
|
Array.from(el.querySelectorAll(`${cfg.childTagString}`))
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(checkboxEls.map(checkboxEl => checkboxEl.checked)).to.eql([true, false, false]);
|
||||||
|
|
||||||
|
// @ts-ignore for testing purposes, we access this protected getter
|
||||||
|
elIndeterminate._inputNode.click();
|
||||||
|
await elIndeterminate.updateComplete;
|
||||||
|
expect(checkboxEls.map(checkboxEl => checkboxEl.checked)).to.eql([true, true, true]);
|
||||||
|
|
||||||
|
// @ts-ignore for testing purposes, we access this protected getter
|
||||||
|
elIndeterminate._inputNode.click();
|
||||||
|
await elIndeterminate.updateComplete;
|
||||||
|
expect(checkboxEls.map(checkboxEl => checkboxEl.checked)).to.eql([false, false, false]);
|
||||||
|
|
||||||
|
// @ts-ignore for testing purposes, we access this protected getter
|
||||||
|
elIndeterminate._inputNode.click();
|
||||||
|
await elIndeterminate.updateComplete;
|
||||||
|
expect(checkboxEls.map(checkboxEl => checkboxEl.checked)).to.eql([true, false, false]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should no longer reach indeterminate state if the child boxes are all checked or all unchecked during indeterminate state', async () => {
|
||||||
|
const el = await fixture(html`
|
||||||
|
<${groupTag} name="scientists[]">
|
||||||
|
<${tag} mixed-state label="Favorite scientists">
|
||||||
|
<${childTag} label="Archimedes" checked></${childTag}>
|
||||||
|
<${childTag} label="Francis Bacon"></${childTag}>
|
||||||
|
<${childTag} label="Marie Curie"></${childTag}>
|
||||||
|
</${tag}>
|
||||||
|
</${groupTag}>
|
||||||
|
`);
|
||||||
|
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
|
el.querySelector(`${cfg.tagString}`)
|
||||||
|
);
|
||||||
|
const checkboxEls = /** @type {LionCheckbox[]} */ (
|
||||||
|
Array.from(el.querySelectorAll(`${cfg.childTagString}`))
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check when all child boxes in indeterminate state are unchecked
|
||||||
|
// we don't have a tri-state, but a duo-state.
|
||||||
|
|
||||||
|
// @ts-ignore for testing purposes, we access this protected getter
|
||||||
|
checkboxEls[0]._inputNode.click();
|
||||||
|
await elIndeterminate.updateComplete;
|
||||||
|
|
||||||
|
// @ts-ignore for testing purposes, we access this protected getter
|
||||||
|
elIndeterminate._inputNode.click();
|
||||||
|
await elIndeterminate.updateComplete;
|
||||||
|
expect(elIndeterminate.checked).to.be.true;
|
||||||
|
expect(elIndeterminate.indeterminate).to.be.false;
|
||||||
|
|
||||||
|
// @ts-ignore for testing purposes, we access this protected getter
|
||||||
|
elIndeterminate._inputNode.click();
|
||||||
|
await elIndeterminate.updateComplete;
|
||||||
|
expect(elIndeterminate.checked).to.be.false;
|
||||||
|
expect(elIndeterminate.indeterminate).to.be.false;
|
||||||
|
|
||||||
|
// @ts-ignore for testing purposes, we access this protected getter
|
||||||
|
elIndeterminate._inputNode.click();
|
||||||
|
await elIndeterminate.updateComplete;
|
||||||
|
expect(elIndeterminate.checked).to.be.true;
|
||||||
|
expect(elIndeterminate.indeterminate).to.be.false;
|
||||||
|
|
||||||
|
// Check when all child boxes in indeterminate state are getting checked
|
||||||
|
// we also don't have a tri-state, but a duo-state.
|
||||||
|
|
||||||
|
// @ts-ignore for testing purposes, we access this protected getter
|
||||||
|
elIndeterminate._inputNode.click(); // unchecked
|
||||||
|
await elIndeterminate.updateComplete;
|
||||||
|
for (const checkEl of checkboxEls) {
|
||||||
|
// @ts-ignore for testing purposes, we access this protected getter
|
||||||
|
checkEl._inputNode.click();
|
||||||
|
// Give each checking of the sub checkbox a chance to finish updating
|
||||||
|
// This means indeterminate state will be true for a bit and the state gets stored
|
||||||
|
await checkEl.updateComplete;
|
||||||
|
await elIndeterminate.updateComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(elIndeterminate.checked).to.be.true;
|
||||||
|
expect(elIndeterminate.indeterminate).to.be.false;
|
||||||
|
|
||||||
|
// @ts-ignore for testing purposes, we access this protected getter
|
||||||
|
elIndeterminate._inputNode.click();
|
||||||
|
await elIndeterminate.updateComplete;
|
||||||
|
expect(elIndeterminate.checked).to.be.false;
|
||||||
|
expect(elIndeterminate.indeterminate).to.be.false;
|
||||||
|
|
||||||
|
// @ts-ignore for testing purposes, we access this protected getter
|
||||||
|
elIndeterminate._inputNode.click();
|
||||||
|
await elIndeterminate.updateComplete;
|
||||||
|
expect(elIndeterminate.checked).to.be.true;
|
||||||
|
expect(elIndeterminate.indeterminate).to.be.false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('accessibility', () => {
|
||||||
|
it('is accessible', async () => {
|
||||||
|
const el = /** @type {LionCheckboxGroup} */ (
|
||||||
|
await fixture(html`
|
||||||
|
<${groupTag} name="scientists[]">
|
||||||
|
<${tag} label="Favorite scientists">
|
||||||
|
<${childTag} label="Archimedes" checked></${childTag}>
|
||||||
|
<${childTag} label="Francis Bacon"></${childTag}>
|
||||||
|
<${childTag} label="Marie Curie"></${childTag}>
|
||||||
|
</${tag}>
|
||||||
|
</${groupTag}>
|
||||||
|
`)
|
||||||
|
);
|
||||||
|
await expect(el).to.be.accessible();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('has role="list" and its children role="listitem"', async () => {
|
||||||
|
const el = await fixture(html`
|
||||||
|
<${groupTag} name="scientists[]">
|
||||||
|
<${tag} label="Favorite scientists">
|
||||||
|
<${childTag} label="Archimedes" checked></${childTag}>
|
||||||
|
<${childTag} label="Francis Bacon"></${childTag}>
|
||||||
|
<${childTag} label="Marie Curie"></${childTag}>
|
||||||
|
</${tag}>
|
||||||
|
</${groupTag}>
|
||||||
|
`);
|
||||||
|
const elIndeterminate = /** @type {LionCheckboxIndeterminate} */ (
|
||||||
|
el.querySelector(`${cfg.tagString}`)
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
elIndeterminate.shadowRoot
|
||||||
|
?.querySelector('.choice-field__nested-checkboxes')
|
||||||
|
?.getAttribute('role'),
|
||||||
|
).to.equal('list');
|
||||||
|
expect(elIndeterminate.children[0].getAttribute('role')).to.equal('listitem');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
import '@lion/ui/define/lion-checkbox-indeterminate.js';
|
import '@lion/ui/define/lion-checkbox-indeterminate.js';
|
||||||
|
import '@lion/ui/define/lion-checkbox-group.js';
|
||||||
|
import '@lion/ui/define/lion-checkbox.js';
|
||||||
|
|
||||||
import { runChoiceInputMixinSuite } from '@lion/ui/form-core-test-suites.js';
|
import { runChoiceInputMixinSuite } from '@lion/ui/form-core-test-suites.js';
|
||||||
import { runCheckboxIndeterminateSuite } from '../test-suites/CheckboxIndeterminate.suite.js';
|
import { runCheckboxIndeterminateSuite } from '../test-suites/CheckboxIndeterminate.suite.js';
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue