mirror of
https://github.com/material-components/material-web.git
synced 2024-10-27 06:04:44 +03:00
fix(select): Fix mwc-select for IE and add tests
PiperOrigin-RevId: 297958805
This commit is contained in:
parent
c759cfbc47
commit
97ef53d8a9
@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- CSS custom properties for typography
|
||||
- Added `autoValidate` property on textfield
|
||||
- `mwc-button` now has a slot for `icon` and `trailingIcon`
|
||||
- **BREAKING** setting `mwc-list-item.selected` will update selection in the parent list
|
||||
|
||||
### Changed
|
||||
|
||||
@ -22,12 +23,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- **BREAKING:VISUAL** `mwc-tab`'s default slot now has name `icon`
|
||||
- `mdcFoundation` and `mdcFoundationClass` are now optional in BaseElement.
|
||||
- Remove `export *` from BaseElement and FormElement.
|
||||
- **BREAKING:A11Y** mwc-list will no longer update items on slotchange but on first render and on list item connect meaning list dividers will only add role="separator" in those cases
|
||||
|
||||
### Fixed
|
||||
|
||||
- Setting `scrollTarget` on `mwc-top-app-bar` will update listeners
|
||||
- Fixed sass imports of `_index.scss` files
|
||||
- Fixed issue with caret jumping to end of input on textfield
|
||||
- mwc-list-item now works on IE
|
||||
- mwc-select's `updateComplete` will now properly await child custom elements' `updateComplete`s
|
||||
- **BREAKING** Disabled icon buttons no longer have pointer events
|
||||
- `mwc-textfield` will not set `value` on the internal input tag on `input` event causing caret jumping in Safari
|
||||
- `mwc-select`'s `--mdc-select-ink-color` actually does something now
|
||||
|
||||
## [0.13.0] - 2020-02-03
|
||||
|
||||
|
@ -64,6 +64,6 @@ export class CheckListItemBase extends ListItemBase {
|
||||
super.connectedCallback();
|
||||
this.addEventListener('click', this.boundOnClick);
|
||||
|
||||
this.toggleAttribute('mwc-list-item', true);
|
||||
this.setAttribute('mwc-list-item', '');
|
||||
}
|
||||
}
|
||||
|
@ -201,15 +201,24 @@ export abstract class ListBase extends BaseElement {
|
||||
@keydown=${this.onKeydown}
|
||||
@focusin=${this.onFocusIn}
|
||||
@focusout=${this.onFocusOut}
|
||||
@request-selected=${this.onRequestSelected}>
|
||||
<slot
|
||||
@slotchange=${this.onSlotChange}
|
||||
@list-item-rendered=${this.onListItemConnected}>
|
||||
</slot>
|
||||
@request-selected=${this.onRequestSelected}
|
||||
@list-item-rendered=${this.onListItemConnected}>
|
||||
<slot></slot>
|
||||
</ul>
|
||||
`;
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
super.firstUpdated();
|
||||
|
||||
if (!this.items.length) {
|
||||
// required because this is called before observers
|
||||
this.mdcFoundation.setMulti(this.multi);
|
||||
// for when children upgrade before list
|
||||
this.layout();
|
||||
}
|
||||
}
|
||||
|
||||
protected onFocusIn(evt: FocusEvent) {
|
||||
if (this.mdcFoundation && this.mdcRoot) {
|
||||
const index = this.getIndexOfTarget(evt);
|
||||
|
@ -58,7 +58,7 @@ export class ListItemBase extends LitElement {
|
||||
this.activated = false;
|
||||
this.tabIndex = -1;
|
||||
} else {
|
||||
this.toggleAttribute('mwc-list-item', true);
|
||||
this.setAttribute('mwc-list-item', '');
|
||||
}
|
||||
})
|
||||
noninteractive = false;
|
||||
@ -151,7 +151,7 @@ export class ListItemBase extends LitElement {
|
||||
super.connectedCallback();
|
||||
|
||||
if (!this.noninteractive) {
|
||||
this.toggleAttribute('mwc-list-item', true);
|
||||
this.setAttribute('mwc-list-item', '');
|
||||
}
|
||||
this.addEventListener('click', this.boundOnClick);
|
||||
}
|
||||
|
@ -79,6 +79,6 @@ export class RadioListItemBase extends ListItemBase {
|
||||
super.connectedCallback();
|
||||
this.addEventListener('click', this.boundOnClick);
|
||||
|
||||
this.toggleAttribute('mwc-list-item', true);
|
||||
this.setAttribute('mwc-list-item', '');
|
||||
}
|
||||
}
|
||||
|
@ -290,7 +290,7 @@ export abstract class SelectBase extends FormElement {
|
||||
@selected=${this.onSelected}
|
||||
@opened=${this.onOpened}
|
||||
@closed=${this.onClosed}>
|
||||
<slot></slot>
|
||||
<slot></slot>
|
||||
</mwc-menu>
|
||||
</div>`;
|
||||
}
|
||||
@ -409,6 +409,10 @@ export abstract class SelectBase extends FormElement {
|
||||
}
|
||||
},
|
||||
notifyChange: async (value) => {
|
||||
if (value === this.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.value = value;
|
||||
await this.updateComplete;
|
||||
const ev = new Event('change', {bubbles: true});
|
||||
@ -621,11 +625,11 @@ export abstract class SelectBase extends FormElement {
|
||||
}
|
||||
|
||||
protected async _getUpdateComplete() {
|
||||
await super._getUpdateComplete();
|
||||
await Promise.all([
|
||||
this._outlineUpdateComplete,
|
||||
this._menuUpdateComplete,
|
||||
]);
|
||||
await super._getUpdateComplete();
|
||||
}
|
||||
|
||||
protected async firstUpdated() {
|
||||
|
537
packages/select/src/test/mwc-select.test.ts
Normal file
537
packages/select/src/test/mwc-select.test.ts
Normal file
@ -0,0 +1,537 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2019 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// taze: chai from //third_party/javascript/chai:closure_chai
|
||||
|
||||
import '@material/mwc-list/mwc-list-item';
|
||||
|
||||
import {ListItem} from '@material/mwc-list/mwc-list-item';
|
||||
import {Select} from '@material/mwc-select';
|
||||
import {html} from 'lit-html';
|
||||
|
||||
import {fixture, TestFixture} from '../../../../test/src/util/helpers';
|
||||
|
||||
interface WithSelectedText {
|
||||
selectedText: string;
|
||||
}
|
||||
|
||||
const basic = (outlined = false) => html`
|
||||
<mwc-select ?outlined=${outlined}>
|
||||
<mwc-list-item selected></mwc-list-item>
|
||||
<mwc-list-item value="a">Apple</mwc-list-item>
|
||||
<mwc-list-item value="b">Banana</mwc-list-item>
|
||||
<mwc-list-item value="c">Cucumber</mwc-list-item>
|
||||
</mwc-select>
|
||||
`;
|
||||
|
||||
const validationRequired = (outlined = false) => html`
|
||||
<mwc-select
|
||||
?outlined=${outlined}
|
||||
label="I am required"
|
||||
required>
|
||||
<mwc-list-item selected></mwc-list-item>
|
||||
<mwc-list-item value="a">Apple</mwc-list-item>
|
||||
<mwc-list-item value="b">Banana</mwc-list-item>
|
||||
<mwc-list-item value="c">Cucumber</mwc-list-item>
|
||||
</mwc-select>
|
||||
`;
|
||||
|
||||
const reqInitialVal = (outlined = false) => html`
|
||||
<mwc-select
|
||||
?outlined=${outlined}
|
||||
label="I am required"
|
||||
required
|
||||
validateOnInitialRender>
|
||||
<mwc-list-item selected></mwc-list-item>
|
||||
<mwc-list-item value="a">Apple</mwc-list-item>
|
||||
<mwc-list-item value="b">Banana</mwc-list-item>
|
||||
<mwc-list-item value="c">Cucumber</mwc-list-item>
|
||||
</mwc-select>
|
||||
`;
|
||||
|
||||
const itemsTemplate = html`
|
||||
<mwc-list-item></mwc-list-item>
|
||||
<mwc-list-item value="a">Apple</mwc-list-item>
|
||||
<mwc-list-item value="b">Banana</mwc-list-item>
|
||||
<mwc-list-item value="c" selected>Cucumber</mwc-list-item>`;
|
||||
|
||||
const lazy = (template = html``) => html`
|
||||
<mwc-select>
|
||||
${template}
|
||||
</mwc-select>
|
||||
`;
|
||||
|
||||
const isUiInvalid = (element: Select) => {
|
||||
return !!element.shadowRoot!.querySelector('.mdc-select--invalid');
|
||||
};
|
||||
|
||||
suite('mwc-select:', () => {
|
||||
let fixt: TestFixture;
|
||||
|
||||
suite('basic', () => {
|
||||
let element: Select;
|
||||
setup(async () => {
|
||||
fixt = await fixture(basic());
|
||||
|
||||
element = fixt.root.querySelector('mwc-select')!;
|
||||
});
|
||||
|
||||
test('initializes as an mwc-select', () => {
|
||||
assert.instanceOf(element, Select);
|
||||
});
|
||||
|
||||
test('setting value sets on input', async () => {
|
||||
element.value = 'my test value';
|
||||
|
||||
const inputElement = element.shadowRoot!.querySelector('input');
|
||||
assert(inputElement, 'my test value');
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
if (fixt) {
|
||||
fixt.remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
suite('validation', () => {
|
||||
suite('standard', () => {
|
||||
test('required invalidates on blur', async () => {
|
||||
fixt = await fixture(validationRequired());
|
||||
const element = fixt.root.querySelector('mwc-select')!;
|
||||
|
||||
assert.isFalse(isUiInvalid(element), 'ui initially valid');
|
||||
element.focus();
|
||||
await element.updateComplete;
|
||||
assert.isFalse(isUiInvalid(element), 'no validation on focus');
|
||||
element.blur();
|
||||
await element.updateComplete;
|
||||
assert.isTrue(isUiInvalid(element), 'invalid after blur');
|
||||
});
|
||||
|
||||
test('validity & checkValidity do not trigger ui', async () => {
|
||||
fixt = await fixture(validationRequired());
|
||||
const element = fixt.root.querySelector('mwc-select')!;
|
||||
assert.isFalse(isUiInvalid(element), 'ui initially valid');
|
||||
|
||||
let invalidCalled = false;
|
||||
element.addEventListener('invalid', () => invalidCalled = true);
|
||||
|
||||
const validity = element.validity;
|
||||
|
||||
assert.isTrue(validity.valueMissing, 'validation fails - required');
|
||||
assert.isFalse(validity.valid, 'element is invalid');
|
||||
assert.isFalse(
|
||||
invalidCalled, 'invalid event not fired because of .validity');
|
||||
assert.isFalse(
|
||||
isUiInvalid(element), 'ui is not invalid because of .validity');
|
||||
|
||||
const checkValidity = element.checkValidity();
|
||||
|
||||
assert.isFalse(
|
||||
checkValidity, 'check validity returns false when invalid');
|
||||
assert.isTrue(invalidCalled, 'invalid event called');
|
||||
assert.isFalse(isUiInvalid(element), 'ui is invalid');
|
||||
});
|
||||
|
||||
test('setCustomValidity', async () => {
|
||||
fixt = await fixture(basic());
|
||||
const element = fixt.root.querySelector('mwc-select')!;
|
||||
|
||||
assert.isFalse(isUiInvalid(element), 'ui initially valid');
|
||||
assert.equal(element.validationMessage, '');
|
||||
|
||||
const validationMsgProp = 'set on prop';
|
||||
element.validationMessage = validationMsgProp;
|
||||
assert.isFalse(
|
||||
isUiInvalid(element),
|
||||
'ui not false due to setting validationMessage');
|
||||
assert.equal(
|
||||
element.validationMessage,
|
||||
validationMsgProp,
|
||||
'setting validationMessage works');
|
||||
|
||||
const validationMsgFn = 'set by setCustomValidity';
|
||||
element.setCustomValidity(validationMsgFn);
|
||||
|
||||
assert.equal(
|
||||
element.validationMessage,
|
||||
validationMsgFn,
|
||||
'validationMessage prop is set with setCustomValidity');
|
||||
|
||||
const validity = element.validity;
|
||||
assert.isTrue(
|
||||
validity.customError, 'customError is reason for valitity failure');
|
||||
assert.isFalse(validity.valid, 'element is not valid');
|
||||
});
|
||||
|
||||
test('validity transform', async () => {
|
||||
fixt = await fixture(basic());
|
||||
const element = fixt.root.querySelector('mwc-select')! as Select;
|
||||
|
||||
assert.isTrue(element.checkValidity(), 'element is initially valid');
|
||||
|
||||
const transformFn =
|
||||
(value: string, vState: ValidityState): Partial<ValidityState> => {
|
||||
if (value === 'a') {
|
||||
return {
|
||||
valid: true,
|
||||
};
|
||||
} else if (vState.valid) {
|
||||
const isOutOfRange = value === 'c';
|
||||
if (isOutOfRange) {
|
||||
return {
|
||||
valid: false,
|
||||
rangeOverflow: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
element.validityTransform = transformFn;
|
||||
|
||||
let validity = element.validity;
|
||||
assert.isTrue(validity.valid, 'unhandled case is valid');
|
||||
assert.isTrue(
|
||||
element.checkValidity(),
|
||||
'checkValidity is true for unhandled case');
|
||||
|
||||
element.select(1);
|
||||
await element.updateComplete;
|
||||
validity = element.validity;
|
||||
assert.isTrue(validity.valid, 'explicitly handled value is true');
|
||||
assert.isTrue(
|
||||
element.reportValidity(),
|
||||
'checkValidity is true for explicit case');
|
||||
|
||||
assert.isFalse(
|
||||
isUiInvalid(element), 'reportValidity makes ui valid when valid');
|
||||
|
||||
element.select(3);
|
||||
await element.updateComplete;
|
||||
validity = element.validity;
|
||||
|
||||
assert.isFalse(validity.valid, 'explicitly false case returns false');
|
||||
assert.isTrue(
|
||||
validity.rangeOverflow, 'explicit reason for invalid set');
|
||||
assert.isFalse(
|
||||
element.reportValidity(),
|
||||
'checkValidity is true for explicitly invalid case');
|
||||
|
||||
assert.isTrue(
|
||||
isUiInvalid(element),
|
||||
'reportValidity makes ui invalid when invalid');
|
||||
|
||||
element.select(2);
|
||||
await element.updateComplete;
|
||||
validity = element.validity;
|
||||
|
||||
assert.isTrue(validity.valid, 'validity can be set back to true');
|
||||
assert.isFalse(
|
||||
validity.rangeOverflow, 'explicit reason for invalid unset');
|
||||
assert.isTrue(
|
||||
element.reportValidity(),
|
||||
'checkValidity is set back true for valid case');
|
||||
|
||||
assert.isFalse(isUiInvalid(element), 'ui can be made valid again');
|
||||
});
|
||||
|
||||
test('initial validation', async () => {
|
||||
fixt = await fixture(reqInitialVal());
|
||||
let element = fixt.root.querySelector('mwc-select')!;
|
||||
await element.updateComplete;
|
||||
assert.isTrue(isUiInvalid(element), 'initial render is invalid');
|
||||
|
||||
fixt.remove();
|
||||
|
||||
fixt = await fixture(validationRequired());
|
||||
element = fixt.root.querySelector('mwc-select')!;
|
||||
await element.updateComplete;
|
||||
assert.isFalse(isUiInvalid(element), 'without flag is valid');
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
if (fixt) {
|
||||
fixt.remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
suite('outlined', () => {
|
||||
test('required invalidates on blur', async () => {
|
||||
fixt = await fixture(validationRequired(true));
|
||||
const element = fixt.root.querySelector('mwc-select')!;
|
||||
|
||||
assert.isFalse(isUiInvalid(element), 'ui initially valid');
|
||||
element.focus();
|
||||
await element.updateComplete;
|
||||
assert.isFalse(isUiInvalid(element), 'no validation on focus');
|
||||
element.blur();
|
||||
await element.updateComplete;
|
||||
assert.isTrue(isUiInvalid(element), 'invalid after blur');
|
||||
});
|
||||
|
||||
test('validity & checkValidity do not trigger ui', async () => {
|
||||
fixt = await fixture(validationRequired(true));
|
||||
const element = fixt.root.querySelector('mwc-select')!;
|
||||
assert.isFalse(isUiInvalid(element), 'ui initially valid');
|
||||
|
||||
let invalidCalled = false;
|
||||
element.addEventListener('invalid', () => invalidCalled = true);
|
||||
|
||||
const validity = element.validity;
|
||||
|
||||
assert.isTrue(validity.valueMissing, 'validation fails - required');
|
||||
assert.isFalse(validity.valid, 'element is invalid');
|
||||
assert.isFalse(
|
||||
invalidCalled, 'invalid event not fired because of .validity');
|
||||
assert.isFalse(
|
||||
isUiInvalid(element), 'ui is not invalid because of .validity');
|
||||
|
||||
const checkValidity = element.checkValidity();
|
||||
|
||||
assert.isFalse(
|
||||
checkValidity, 'check validity returns false when invalid');
|
||||
assert.isTrue(invalidCalled, 'invalid event called');
|
||||
assert.isFalse(isUiInvalid(element), 'ui is invalid');
|
||||
});
|
||||
|
||||
test('setCustomValidity', async () => {
|
||||
fixt = await fixture(basic(true));
|
||||
const element = fixt.root.querySelector('mwc-select')!;
|
||||
await element.updateComplete;
|
||||
|
||||
assert.isFalse(isUiInvalid(element));
|
||||
assert.equal(element.validationMessage, '');
|
||||
|
||||
const validationMsgProp = 'set on prop';
|
||||
element.validationMessage = validationMsgProp;
|
||||
assert.isFalse(isUiInvalid(element));
|
||||
assert.equal(element.validationMessage, validationMsgProp);
|
||||
|
||||
const validationMsgFn = 'set by setCustomValidity';
|
||||
element.setCustomValidity(validationMsgFn);
|
||||
|
||||
assert.equal(element.validationMessage, validationMsgFn);
|
||||
|
||||
const validity = element.validity;
|
||||
assert.isTrue(validity.customError);
|
||||
assert.isFalse(validity.valid);
|
||||
});
|
||||
|
||||
test('validity transform', async () => {
|
||||
fixt = await fixture(basic(true));
|
||||
const element = fixt.root.querySelector('mwc-select')! as Select;
|
||||
|
||||
assert.isTrue(element.checkValidity(), 'element is initially valid');
|
||||
|
||||
const transformFn =
|
||||
(value: string, vState: ValidityState): Partial<ValidityState> => {
|
||||
if (value === 'a') {
|
||||
return {
|
||||
valid: true,
|
||||
};
|
||||
} else if (vState.valid) {
|
||||
const isOutOfRange = value === 'c';
|
||||
if (isOutOfRange) {
|
||||
return {
|
||||
valid: false,
|
||||
rangeOverflow: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
element.validityTransform = transformFn;
|
||||
|
||||
let validity = element.validity;
|
||||
assert.isTrue(validity.valid, 'unhandled case is valid');
|
||||
assert.isTrue(
|
||||
element.checkValidity(),
|
||||
'checkValidity is true for unhandled case');
|
||||
|
||||
element.select(1);
|
||||
await element.updateComplete;
|
||||
validity = element.validity;
|
||||
assert.isTrue(validity.valid, 'explicitly handled value is true');
|
||||
assert.isTrue(
|
||||
element.reportValidity(),
|
||||
'checkValidity is true for explicit case');
|
||||
|
||||
assert.isFalse(
|
||||
isUiInvalid(element), 'reportValidity makes ui valid when valid');
|
||||
|
||||
element.select(3);
|
||||
await element.updateComplete;
|
||||
validity = element.validity;
|
||||
|
||||
assert.isFalse(validity.valid, 'explicitly false case returns false');
|
||||
assert.isTrue(
|
||||
validity.rangeOverflow, 'explicit reason for invalid set');
|
||||
assert.isFalse(
|
||||
element.reportValidity(),
|
||||
'checkValidity is true for explicitly invalid case');
|
||||
|
||||
assert.isTrue(
|
||||
isUiInvalid(element),
|
||||
'reportValidity makes ui invalid when invalid');
|
||||
|
||||
element.select(2);
|
||||
await element.updateComplete;
|
||||
validity = element.validity;
|
||||
|
||||
assert.isTrue(validity.valid, 'validity can be set back to true');
|
||||
assert.isFalse(
|
||||
validity.rangeOverflow, 'explicit reason for invalid unset');
|
||||
assert.isTrue(
|
||||
element.reportValidity(),
|
||||
'checkValidity is set back true for valid case');
|
||||
|
||||
assert.isFalse(isUiInvalid(element), 'ui can be made valid again');
|
||||
});
|
||||
|
||||
test('initial validation', async () => {
|
||||
fixt = await fixture(reqInitialVal(true));
|
||||
let element = fixt.root.querySelector('mwc-select')!;
|
||||
await element.updateComplete;
|
||||
assert.isTrue(isUiInvalid(element), 'initial render is invalid');
|
||||
|
||||
fixt.remove();
|
||||
|
||||
fixt = await fixture(validationRequired(true));
|
||||
element = fixt.root.querySelector('mwc-select')!;
|
||||
await element.updateComplete;
|
||||
assert.isFalse(isUiInvalid(element), 'without flag is valid');
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
if (fixt) {
|
||||
fixt.remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
suite('selection', () => {
|
||||
let element: Select;
|
||||
let changeCalls = 0;
|
||||
const changeListener = () => {
|
||||
changeCalls++;
|
||||
};
|
||||
|
||||
setup(async () => {
|
||||
fixt = await fixture(basic());
|
||||
|
||||
element = fixt.root.querySelector('mwc-select')!;
|
||||
element.addEventListener('change', changeListener);
|
||||
|
||||
await element.updateComplete;
|
||||
});
|
||||
|
||||
test('selection via index', async () => {
|
||||
assert.equal(changeCalls, 0, 'change evt not called on startup');
|
||||
assert.equal(element.value, '', 'initial value is blank');
|
||||
assert.equal(
|
||||
(element as unknown as WithSelectedText).selectedText,
|
||||
'',
|
||||
'selectedText is blank');
|
||||
assert.isTrue(!!element.selected, 'there is a selected element');
|
||||
|
||||
const firstElement = element.querySelector('mwc-list-item')!;
|
||||
assert.isTrue(firstElement.selected, 'the element has selected prop');
|
||||
|
||||
element.select(1);
|
||||
await element.updateComplete;
|
||||
assert.equal(changeCalls, 1, 'change event called once on selection');
|
||||
changeCalls = 0;
|
||||
|
||||
assert.equal(element.value, 'a', 'select method updates value');
|
||||
assert.isTrue(
|
||||
(element as unknown as WithSelectedText).selectedText === 'Apple',
|
||||
'selectedText is updated');
|
||||
assert.isTrue(
|
||||
!!element.selected, 'there is a selected element after select');
|
||||
|
||||
const aElement = element.querySelector('[value="a"]') as ListItem;
|
||||
assert.isFalse(firstElement.selected, 'the previous has be deselected');
|
||||
assert.isTrue(aElement.selected, 'the element has selected prop');
|
||||
assert.isTrue(
|
||||
aElement === element.selected,
|
||||
'element with selected prop is the same as selected on mwc-select');
|
||||
});
|
||||
|
||||
test('selection via element', async () => {
|
||||
assert.equal(changeCalls, 0, 'change evt not called on startup');
|
||||
assert.equal(element.value, '', 'initial value is blank');
|
||||
assert.isTrue(
|
||||
(element as unknown as WithSelectedText).selectedText === '',
|
||||
'selectedText is blank');
|
||||
assert.isTrue(!!element.selected, 'there is a selected element');
|
||||
|
||||
const firstElement = element.querySelector('mwc-list-item')!;
|
||||
assert.isTrue(firstElement.selected, 'the element has selected prop');
|
||||
|
||||
const aElement = element.querySelector('[value="a"]') as ListItem;
|
||||
aElement.selected = true;
|
||||
await aElement.updateComplete;
|
||||
await element.updateComplete;
|
||||
assert.equal(changeCalls, 1, 'change event called once on selection');
|
||||
changeCalls = 0;
|
||||
|
||||
assert.equal(element.value, 'a', 'select method updates value');
|
||||
assert.isTrue(
|
||||
(element as unknown as WithSelectedText).selectedText === 'Apple',
|
||||
'selectedText is updated');
|
||||
assert.isTrue(
|
||||
!!element.selected, 'there is a selected element after select');
|
||||
|
||||
assert.isFalse(firstElement.selected, 'the previous has be deselected');
|
||||
assert.isTrue(aElement.selected, 'the element has selected prop');
|
||||
assert.isTrue(
|
||||
aElement === element.selected,
|
||||
'element with selected prop is the same as selected on mwc-select');
|
||||
});
|
||||
|
||||
test('lazy selection', async () => {
|
||||
fixt.remove();
|
||||
fixt = await fixture(lazy());
|
||||
element = fixt.root.querySelector('mwc-select')!;
|
||||
|
||||
assert.equal(element.index, -1, 'unselected index when no children');
|
||||
|
||||
fixt.template = lazy(itemsTemplate);
|
||||
await fixt.updateComplete;
|
||||
await element.updateComplete;
|
||||
|
||||
assert.equal(element.index, 3, 'index updates when lazily slotted');
|
||||
assert.equal(element.value, 'c', 'value updates when lazily slotted');
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
if (fixt) {
|
||||
fixt.remove();
|
||||
}
|
||||
|
||||
element.removeEventListener('change', changeListener);
|
||||
changeCalls = 0;
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user