fix: upgrade to latest scoped elements, add missing types

This commit is contained in:
Joren Broekema 2021-01-14 13:08:23 +01:00
parent 8fb7e7a193
commit 9112d243db
18 changed files with 295 additions and 196 deletions

View file

@ -0,0 +1,23 @@
---
'@lion/calendar': patch
'@lion/checkbox-group': patch
'@lion/combobox': patch
'@lion/core': patch
'@lion/fieldset': patch
'@lion/form-core': patch
'@lion/form-integrations': patch
'@lion/input-date': patch
'@lion/input-datepicker': patch
'@lion/input-email': patch
'@lion/input-iban': patch
'@lion/listbox': patch
'@lion/localize': patch
'@lion/overlays': patch
'@lion/pagination': patch
'@lion/progress-indicator': patch
'@lion/radio-group': patch
'@lion/select-rich': patch
'@lion/switch': patch
---
Fix missing types and update to latest scoped elements to fix constructor type.

View file

@ -445,7 +445,7 @@ export class GoogleCombobox extends LionCombobox {
}
_showOverlayCondition(options) {
return this.focused || super.showOverlayCondition(options);
return this.focused || super._showOverlayCondition(options);
}
__resetFocus() {

View file

@ -372,7 +372,7 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
*
* @example
* _showOverlayCondition(options) {
* return this.focused || super.showOverlayCondition(options);
* return this.focused || super._showOverlayCondition(options);
* }
*
* @example
@ -382,7 +382,7 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
*
* @example
* _showOverlayCondition(options) {
* return options.currentValue.length > 4 && super.showOverlayCondition(options);
* return options.currentValue.length > 4 && super._showOverlayCondition(options);
* }
*
* @param {{ currentValue: string, lastKey:string }} options

View file

@ -8,7 +8,6 @@ import { Required } from '@lion/form-core';
import { LionCombobox } from '../src/LionCombobox.js';
/**
* @typedef {import('../src/LionCombobox.js').LionCombobox} LionCombobox
* @typedef {import('../types/SelectionDisplay').SelectionDisplay} SelectionDisplay
*/
@ -384,8 +383,9 @@ describe('lion-combobox', () => {
describe('Subclassers', () => {
it('allows to control overlay visibility via "_showOverlayCondition"', async () => {
class ShowOverlayConditionCombobox extends LionCombobox {
/** @param {{ currentValue: string, lastKey:string }} options */
_showOverlayCondition(options) {
return this.focused || super.showOverlayCondition(options);
return this.focused || super._showOverlayCondition(options);
}
}
const tagName = defineCE(ShowOverlayConditionCombobox);
@ -575,6 +575,7 @@ describe('lion-combobox', () => {
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
</lion-combobox>
`));
// @ts-ignore sinon type error
const spy = sinon.spy(el._selectionDisplayNode, 'onComboboxElementUpdated');
el.requestUpdate('modelValue');
await el.updateComplete;
@ -823,6 +824,11 @@ describe('lion-combobox', () => {
`));
expect(el._inputNode.value).to.equal('');
/**
* @param {'none' | 'list' | 'inline' | 'both'} autocomplete
* @param {number|number[]} index
* @param {string} valueOnClose
*/
async function performChecks(autocomplete, index, valueOnClose) {
await el.updateComplete;
el.opened = true;
@ -945,7 +951,7 @@ describe('lion-combobox', () => {
`));
// This ensures autocomplete would be off originally
el.autocomplete = 'list';
await mimicUserTypingAdvanced(el, 'vi'); // so we have options ['Victoria Plum']
await mimicUserTypingAdvanced(el, ['v', 'i']); // so we have options ['Victoria Plum']
await el.updateComplete;
expect(el.checkedIndex).to.equal(3);
});
@ -1057,6 +1063,10 @@ describe('lion-combobox', () => {
return true;
}
/**
* @param {?} modelValue
* @param {?} oldModelValue
*/
// eslint-disable-next-line no-unused-vars
_syncToTextboxMultiple(modelValue, oldModelValue) {
// In a real scenario (depending on how selection display works),

View file

@ -32,7 +32,7 @@
"sideEffects": false,
"dependencies": {
"@open-wc/dedupe-mixin": "^1.2.18",
"@open-wc/scoped-elements": "^1.3.2",
"@open-wc/scoped-elements": "^1.3.3",
"lit-element": "~2.4.0",
"lit-html": "^1.3.0"
},

View file

@ -1,10 +1,14 @@
import { expect, fixture, html } from '@open-wc/testing';
import './helpers/umbrella-form.js';
/**
* @typedef {import('./helpers/umbrella-form.js').UmbrellaForm} UmbrellaForm
*/
// Test umbrella form.
describe('Form Integrations', () => {
it('".serializedValue" returns all non disabled fields based on form structure', async () => {
const el = await fixture(html`<umbrella-form></umbrella-form>`);
const el = /** @type {UmbrellaForm} */ (await fixture(html`<umbrella-form></umbrella-form>`));
await el.updateComplete;
const formEl = el._lionFormNode;
expect(formEl.serializedValue).to.eql({
@ -29,7 +33,7 @@ describe('Form Integrations', () => {
});
it('".formattedValue" returns all non disabled fields based on form structure', async () => {
const el = await fixture(html`<umbrella-form></umbrella-form>`);
const el = /** @type {UmbrellaForm} */ (await fixture(html`<umbrella-form></umbrella-form>`));
await el.updateComplete;
const formEl = el._lionFormNode;
expect(formEl.formattedValue).to.eql({

View file

@ -18,6 +18,7 @@ import '@lion/textarea/lion-textarea';
import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
describe(`Submitting/Resetting Form`, async () => {
/** @type {import('@lion/form').LionForm} */
let el;
beforeEach(async () => {
el = await fixture(html`
@ -121,7 +122,7 @@ describe(`Submitting/Resetting Form`, async () => {
});
it('Submitting a form should make submitted true for all fields', async () => {
el.querySelector('#submit_button').click();
/** @type {import('@lion/button').LionButton} */ (el.querySelector('#submit_button')).click();
await elementUpdated(el);
await el.updateComplete;
el.formElements.forEach(field => {
@ -130,8 +131,8 @@ describe(`Submitting/Resetting Form`, async () => {
});
it('Resetting a form should reset metadata of all fields', async () => {
el.querySelector('#submit_button').click();
el.querySelector('#reset_button').click();
/** @type {import('@lion/button').LionButton} */ (el.querySelector('#submit_button')).click();
/** @type {import('@lion/button').LionButton} */ (el.querySelector('#reset_button')).click();
await elementUpdated(el);
await el.updateComplete;
expect(el.submitted).to.be.false;

View file

@ -22,7 +22,9 @@ import '@lion/button/lion-button.js';
export class UmbrellaForm extends LitElement {
get _lionFormNode() {
return this.shadowRoot.querySelector('lion-form');
return /** @type {import('@lion/form').LionForm} */ (this.shadowRoot?.querySelector(
'lion-form',
));
}
render() {
@ -113,8 +115,10 @@ export class UmbrellaForm extends LitElement {
<lion-button
type="button"
raised
@click=${ev =>
ev.currentTarget.parentElement.parentElement.parentElement.resetGroup()}
@click=${() => {
const lionForm = this._lionFormNode;
lionForm.resetGroup();
}}
>Reset</lion-button
>
</div>

View file

@ -29,14 +29,29 @@ import '@lion/fieldset/lion-fieldset.js';
import '@lion/form/lion-form.js';
import '@lion/form-core/lion-field.js';
/**
* @typedef {import('@lion/core').LitElement} LitElement
* @typedef {import('@lion/form-core').LionField} LionField
* @typedef {import('@lion/form-core/types/FormControlMixinTypes').FormControlHost & HTMLElement & {__parentFormGroup?: HTMLElement, checked?: boolean, disabled: boolean, hasFeedbackFor: string[], makeRequestToBeDisabled: Function }} FormControl
* @typedef {import('@lion/input').LionInput} LionInput
* @typedef {import('@lion/select').LionSelect} LionSelect
* @typedef {import('@lion/listbox').LionOption} LionOption
*/
const featureName = 'model value';
const getFirstPaintTitle = count => `should dispatch ${count} time(s) on first paint`;
const getInteractionTitle = count => `should dispatch ${count} time(s) on interaction`;
const getFirstPaintTitle = /** @param {number} count */ count =>
`should dispatch ${count} time(s) on first paint`;
const getInteractionTitle = /** @param {number} count */ count =>
`should dispatch ${count} time(s) on interaction`;
const firstStampCount = 1;
const interactionCount = 1;
/**
* @param {string} tagname
* @param {number} count
*/
const fieldDispatchesCountOnFirstPaint = (tagname, count) => {
const tag = unsafeStatic(tagname);
const spy = sinon.spy();
@ -46,11 +61,15 @@ const fieldDispatchesCountOnFirstPaint = (tagname, count) => {
});
};
/**
* @param {string} tagname
* @param {number} count
*/
const fieldDispatchesCountOnInteraction = (tagname, count) => {
const tag = unsafeStatic(tagname);
const spy = sinon.spy();
it(getInteractionTitle(count), async () => {
const el = await fixture(html`<${tag}></${tag}>`);
const el = /** @type {LionField} */ (await fixture(html`<${tag}></${tag}>`));
el.addEventListener('model-value-changed', spy);
// TODO: discuss if this is the "correct" way to interact with component
el.modelValue = 'foo';
@ -59,6 +78,10 @@ const fieldDispatchesCountOnInteraction = (tagname, count) => {
});
};
/**
* @param {string} tagname
* @param {number} count
*/
const choiceDispatchesCountOnFirstPaint = (tagname, count) => {
const tag = unsafeStatic(tagname);
const spy = sinon.spy();
@ -68,17 +91,28 @@ const choiceDispatchesCountOnFirstPaint = (tagname, count) => {
});
};
/**
* @param {string} tagname
* @param {number} count
*/
const choiceDispatchesCountOnInteraction = (tagname, count) => {
const tag = unsafeStatic(tagname);
const spy = sinon.spy();
it(getInteractionTitle(count), async () => {
const el = await fixture(html`<${tag} .choiceValue="${'option'}"></${tag}>`);
const el = /** @type {HTMLElement & {checked: boolean}} */ (await fixture(
html`<${tag} .choiceValue="${'option'}"></${tag}>`,
));
el.addEventListener('model-value-changed', spy);
el.checked = true;
expect(spy.callCount).to.equal(count);
});
};
/**
* @param {string} groupTagname
* @param {string} itemTagname
* @param {number} count
*/
const choiceGroupDispatchesCountOnFirstPaint = (groupTagname, itemTagname, count) => {
const groupTag = unsafeStatic(groupTagname);
const itemTag = unsafeStatic(itemTagname);
@ -96,6 +130,11 @@ const choiceGroupDispatchesCountOnFirstPaint = (groupTagname, itemTagname, count
});
};
/**
* @param {string} groupTagname
* @param {string} itemTagname
* @param {number} count
*/
const choiceGroupDispatchesCountOnInteraction = (groupTagname, itemTagname, count) => {
const groupTag = unsafeStatic(groupTagname);
const itemTag = unsafeStatic(itemTagname);
@ -110,13 +149,17 @@ const choiceGroupDispatchesCountOnInteraction = (groupTagname, itemTagname, coun
`);
el.addEventListener('model-value-changed', spy);
const option2 = el.querySelector(`${itemTagname}:nth-child(2)`);
const option2 = /** @type {HTMLElement & {checked: boolean}} */ (el.querySelector(
`${itemTagname}:nth-child(2)`,
));
option2.checked = true;
expect(spy.callCount).to.equal(count);
spy.resetHistory();
const option3 = el.querySelector(`${itemTagname}:nth-child(3)`);
const option3 = /** @type {HTMLElement & {checked: boolean}} */ (el.querySelector(
`${itemTagname}:nth-child(3)`,
));
option3.checked = true;
expect(spy.callCount).to.equal(count);
});
@ -178,7 +221,7 @@ describe('lion-select', () => {
it(getInteractionTitle(interactionCount), async () => {
const spy = sinon.spy();
const el = await fixture(html`
const el = /** @type {LionSelect} */ (await fixture(html`
<lion-select>
<select slot="input">
<option value="option1"></option>
@ -186,9 +229,9 @@ describe('lion-select', () => {
<option value="option3"></option>
</select>
</lion-select>
`);
`));
el.addEventListener('model-value-changed', spy);
const option2 = el.querySelector('option:nth-child(2)');
const option2 = /** @type {HTMLOptionElement} */ (el.querySelector('option:nth-child(2)'));
// mimic user input
option2.selected = true;
@ -198,7 +241,7 @@ describe('lion-select', () => {
spy.resetHistory();
const option3 = el.querySelector('option:nth-child(3)');
const option3 = /** @type {HTMLOptionElement} */ (el.querySelector('option:nth-child(3)'));
// mimic user input
option3.selected = true;
@ -238,13 +281,13 @@ describe('lion-select', () => {
`);
el.addEventListener('model-value-changed', spy);
const option2 = el.querySelector('lion-option:nth-child(2)');
const option2 = /** @type {LionOption} */ (el.querySelector('lion-option:nth-child(2)'));
option2.checked = true;
expect(spy.callCount).to.equal(interactionCount);
spy.resetHistory();
const option3 = el.querySelector('lion-option:nth-child(3)');
const option3 = /** @type {LionOption} */ (el.querySelector('lion-option:nth-child(3)'));
option3.checked = true;
expect(spy.callCount).to.equal(interactionCount);
});
@ -274,7 +317,7 @@ describe('lion-fieldset', () => {
`);
el.addEventListener('model-value-changed', spy);
const input = el.querySelector('lion-input');
const input = /** @type {LionInput} */ (el.querySelector('lion-input'));
input.modelValue = 'foo';
expect(spy.callCount).to.equal(interactionCount);
});
@ -337,8 +380,9 @@ describe('detail.isTriggeredByUser', () => {
* - false: when child formElement condition for RegularField is not met
*/
const featureDetectChoiceField = el => 'checked' in el && 'choiceValue' in el;
const featureDetectOptionChoiceField = el => 'active' in el;
const featureDetectChoiceField = /** @param {HTMLElement} el */ el =>
'checked' in el && 'choiceValue' in el;
const featureDetectOptionChoiceField = /** @param {HTMLElement} el */ el => 'active' in el;
/**
* @param {FormControl} el
@ -355,9 +399,8 @@ describe('detail.isTriggeredByUser', () => {
}
/**
* @param {FormControl} el
* @param {FormControl & {value: string}} el
* @param {string} newViewValue
* @returns {'RegularField'|'ChoiceField'|'OptionChoiceField'|'ChoiceGroupField'|'FormOrFieldset'}
*/
function mimicUserInput(el, newViewValue) {
const type = detectType(el);
@ -391,27 +434,39 @@ describe('detail.isTriggeredByUser', () => {
} else if (controlName === 'field') {
childrenEl = await fixture(html`<input slot="input" />`);
}
const el = await fixture(html`<${tag}>${childrenEl}</${tag}>`);
const el = /** @type {LitElement & FormControl & {value: string} & {registrationComplete: Promise<boolean>} & {formElements: Array.<FormControl & {value: string}>}} */ (await fixture(
html`<${tag}>${childrenEl}</${tag}>`,
));
await el.registrationComplete;
el.addEventListener('model-value-changed', spy);
/**
* @param {FormControl & {value: string}} formControl
*/
function expectCorrectEventMetaRegularField(formControl) {
mimicUserInput(formControl, 'userValue', 'RegularField');
mimicUserInput(formControl, 'userValue');
expect(spy.firstCall.args[0].detail.isTriggeredByUser).to.be.true;
// eslint-disable-next-line no-param-reassign
formControl.modelValue = 'programmaticValue';
expect(spy.secondCall.args[0].detail.isTriggeredByUser).to.be.false;
}
/**
* @param {FormControl & {value: string}} formControl
*/
function resetChoiceFieldToForceRepropagation(formControl) {
// eslint-disable-next-line no-param-reassign
formControl.checked = false;
spy.resetHistory();
}
/**
* @param {FormControl & {value: string}} formControl
*/
function expectCorrectEventMetaChoiceField(formControl) {
resetChoiceFieldToForceRepropagation(formControl);
mimicUserInput(formControl, 'userValue', 'ChoiceField');
mimicUserInput(formControl, 'userValue');
expect(spy.firstCall.args[0].detail.isTriggeredByUser).to.be.true;
resetChoiceFieldToForceRepropagation(formControl);

View file

@ -4,20 +4,28 @@ import { expect, html, fixture } from '@open-wc/testing';
// eslint-disable-next-line import/no-extraneous-dependencies
import sinon from 'sinon';
/**
* @typedef {import('@lion/input').LionInput} LionInput
* @typedef {import('@lion/fieldset').LionFieldset} LionFieldset
* @typedef {import('@lion/core').TemplateResult} TemplateResult
*/
const inputFixture = /** @type {(arg: TemplateResult) => Promise<LionInput>} */ (fixture);
const fieldsetFixture = /** @type {(arg: TemplateResult) => Promise<LionFieldset>} */ (fixture);
describe('model value event', () => {
describe('form path', () => {
it('should be property', async () => {
const spy = sinon.spy();
const input = await fixture(html`<lion-input></lion-input>`);
const input = await inputFixture(html`<lion-input></lion-input>`);
input.addEventListener('model-value-changed', spy);
input.modelValue = 'woof';
const e = spy.firstCall.args[0];
expect(e.detail).to.have.a.property('formPath');
expect(e.detail).to.have.property('formPath');
});
it('should contain dispatching field', async () => {
const spy = sinon.spy();
const input = await fixture(html`<lion-input></lion-input>`);
const input = await inputFixture(html`<lion-input></lion-input>`);
input.addEventListener('model-value-changed', spy);
input.modelValue = 'foo';
const e = spy.firstCall.args[0];
@ -26,14 +34,14 @@ describe('model value event', () => {
it('should contain field and group', async () => {
const spy = sinon.spy();
const fieldset = await fixture(html`
const fieldset = await fieldsetFixture(html`
<lion-fieldset name="fieldset">
<lion-input name="input"></lion-input>
</lion-fieldset>
`);
await fieldset.registrationComplete;
fieldset.addEventListener('model-value-changed', spy);
const input = fieldset.querySelector('lion-input');
const input = /** @type {LionInput} */ (fieldset.querySelector('lion-input'));
input.modelValue = 'foo';
const e = spy.firstCall.args[0];
expect(e.detail.formPath).to.eql([input, fieldset]);
@ -41,15 +49,15 @@ describe('model value event', () => {
it('should contain deep elements', async () => {
const spy = sinon.spy();
const grandparent = await fixture(html`
const grandparent = await fieldsetFixture(html`
<lion-fieldset name="grandparent">
<lion-fieldset name="parent">
<lion-input name="input"></lion-input>
</lion-fieldset>
</lion-fieldset>
`);
const parent = grandparent.querySelector('[name=parent]');
const input = grandparent.querySelector('[name=input]');
const parent = /** @type {LionFieldset} */ (grandparent.querySelector('[name=parent]'));
const input = /** @type {LionInput} */ (grandparent.querySelector('[name=input]'));
await grandparent.registrationComplete;
await parent.registrationComplete;
@ -61,7 +69,7 @@ describe('model value event', () => {
it('should ignore elements that are not fields or fieldsets', async () => {
const spy = sinon.spy();
const grandparent = await fixture(html`
const grandparent = await fieldsetFixture(html`
<lion-fieldset name="grandparent">
<div>
<lion-fieldset name="parent">
@ -74,8 +82,8 @@ describe('model value event', () => {
</div>
</lion-fieldset>
`);
const parent = grandparent.querySelector('[name=parent]');
const input = grandparent.querySelector('[name=input]');
const parent = /** @type {LionFieldset} */ (grandparent.querySelector('[name=parent]'));
const input = /** @type {LionInput} */ (grandparent.querySelector('[name=input]'));
await grandparent.registrationComplete;
await parent.registrationComplete;
@ -87,10 +95,11 @@ describe('model value event', () => {
});
describe('signature', () => {
/** @type {?} */
let e;
beforeEach(async () => {
const spy = sinon.spy();
const el = await fixture(html`<lion-input></lion-input>`);
const el = await inputFixture(html`<lion-input></lion-input>`);
el.addEventListener('model-value-changed', spy);
el.modelValue = 'foo';
// eslint-disable-next-line prefer-destructuring
@ -112,18 +121,19 @@ describe('model value event', () => {
describe('propagation', () => {
it('should dispatch different event at each level', async () => {
const grandparent = await fixture(html`
const grandparent = await fieldsetFixture(html`
<lion-fieldset name="grandparent">
<lion-fieldset name="parent">
<lion-input name="input"></lion-input>
</lion-fieldset>
</lion-fieldset>
`);
const parent = grandparent.querySelector('[name="parent"]');
const input = grandparent.querySelector('[name="input"]');
const parent = /** @type {LionFieldset} */ (grandparent.querySelector('[name="parent"]'));
const input = /** @type {LionInput} */ (grandparent.querySelector('[name="input"]'));
await grandparent.registrationComplete;
await parent.registrationComplete;
/** @type {sinon.SinonSpy[]} */
const spies = [];
[grandparent, parent, input].forEach(element => {
const spy = sinon.spy();

View file

@ -1,7 +1,7 @@
/**
* Whether first element contains the second element, also goes through shadow roots
* @param {HTMLElement|ShadowRoot} el
* @param {HTMLElement} targetEl
* @param {HTMLElement|ShadowRoot} targetEl
* @returns {boolean}
*/
export function deepContains(el, targetEl) {

View file

@ -6,8 +6,8 @@
* Compares two OverlayConfigs to equivalence. Intended to prevent unnecessary resets.
* Note that it doesn't cover as many use cases as common implementations, such as Lodash isEqual.
*
* @param {OverlayConfig} a
* @param {OverlayConfig} b
* @param {Partial<OverlayConfig>} a
* @param {Partial<OverlayConfig>} b
* @returns {boolean} Whether the configs are equivalent
*/
export function isEqualConfig(a, b) {

View file

@ -1,5 +1,4 @@
import { expect, fixture, html } from '@open-wc/testing';
// @ts-expect-error
import { renderLitAsNode } from '@lion/helpers';
import { getDeepActiveElement } from '../../src/utils/get-deep-active-element.js';
import { getFocusableElements } from '../../src/utils/get-focusable-elements.js';
@ -72,9 +71,11 @@ function createShadowDomNode() {
<button id="outside-2">outside 2</button>
</div>
`);
const rootElementShadow = shadowDomNode.querySelector('#rootElementShadow');
rootElementShadow.attachShadow({ mode: 'open' });
rootElementShadow.shadowRoot.appendChild(interactionElementsNode);
const rootElementShadow = shadowDomNode?.querySelector('#rootElementShadow');
rootElementShadow?.attachShadow({ mode: 'open' });
if (interactionElementsNode) {
rootElementShadow?.shadowRoot?.appendChild(interactionElementsNode);
}
return shadowDomNode;
}

View file

@ -30,7 +30,12 @@ describe('deepContains()', () => {
expect(deepContains(shadowRoot, shadowElementChild)).to.be.true;
// Siblings
expect(deepContains(element.firstElementChild, element.lastElementChild)).to.be.false;
expect(
deepContains(
/** @type {HTMLElement} */ (element.firstElementChild),
/** @type {HTMLElement} */ (element.lastElementChild),
),
).to.be.false;
// Unrelated
expect(deepContains(lightChildEl, shadowElementChild)).to.be.false;
});
@ -95,16 +100,19 @@ describe('deepContains()', () => {
</div>
`));
expect(deepContains(element, element.firstElementChild)).to.be.true;
expect(deepContains(element, element.firstElementChild.shadowRoot)).to.be.true;
expect(deepContains(element, element.firstElementChild.shadowRoot.children[1])).to.be.true;
expect(deepContains(element, element.firstElementChild.shadowRoot.children[1].shadowRoot)).to.be
.true;
expect(
deepContains(
element,
element.firstElementChild.shadowRoot.children[1].shadowRoot.lastElementChild,
),
).to.be.true;
const elementFirstChild = /** @type {HTMLElement} */ (element.firstElementChild);
const elementFirstChildShadow = /** @type {ShadowRoot} */ (elementFirstChild.shadowRoot);
const elementFirstChildShadowChildren = /** @type {HTMLElement[]} */ (Array.from(
elementFirstChildShadow.children,
));
const elementFirstChildShadowChildShadow = /** @type {ShadowRoot} */ (elementFirstChildShadowChildren[1]
.shadowRoot);
const elementFirstChildShadowChildShadowLastChild = /** @type {HTMLElement} */ (elementFirstChildShadowChildShadow.lastElementChild);
expect(deepContains(element, elementFirstChild)).to.be.true;
expect(deepContains(element, elementFirstChildShadow)).to.be.true;
expect(deepContains(element, elementFirstChildShadowChildren[1])).to.be.true;
expect(deepContains(element, elementFirstChildShadowChildShadow)).to.be.true;
expect(deepContains(element, elementFirstChildShadowChildShadowLastChild)).to.be.true;
});
});

View file

@ -3,14 +3,15 @@ import { isEqualConfig } from '../../src/utils/is-equal-config.js';
function TestConfig() {
return {
placementMode: 'local',
placementMode: /** @type {'local'|'global'} */ ('local'),
hidesOnOutsideClick: true,
popperConfig: {
modifiers: {
offset: {
modifiers: [
{
name: 'offset',
enabled: false,
},
},
],
},
};
}
@ -31,13 +32,13 @@ describe('isEqualConfig()', () => {
it('compares prop count', () => {
const config = TestConfig();
expect(isEqualConfig(config, { ...config, extra: 'value' })).eql(false);
expect(isEqualConfig({ ...config, extra: 'value' }, config)).eql(false);
expect(isEqualConfig(config, { ...config, isBlocking: true })).eql(false);
expect(isEqualConfig({ ...config, isBlocking: true }, config)).eql(false);
});
it('regards missing props different from ones with undefined value', () => {
const config = TestConfig();
expect(isEqualConfig(config, { ...config, extra: undefined })).eql(false);
expect(isEqualConfig(config, { ...config, referenceNode: undefined })).eql(false);
});
it('compares nested props', () => {
@ -46,12 +47,7 @@ describe('isEqualConfig()', () => {
...config,
popperConfig: {
...config.popperConfig,
modifiers: {
...config.popperConfig.modifiers,
offset: {
...config.popperConfig.modifiers.offset,
},
},
modifiers: [...config.popperConfig.modifiers],
},
};
expect(isEqualConfig(config, sameConfig)).eql(true);
@ -59,12 +55,13 @@ describe('isEqualConfig()', () => {
...config,
popperConfig: {
...config.popperConfig,
modifiers: {
modifiers: [
...config.popperConfig.modifiers,
offset: {
enabled: !config.popperConfig.modifiers.offset.enabled,
{
name: 'offset',
enabled: !config.popperConfig.modifiers.find(mod => mod.name === 'offset')?.enabled,
},
},
],
},
};
expect(isEqualConfig(config, differentConfig)).eql(false);

View file

@ -1,5 +1,4 @@
import { LitElement } from '@lion/core';
// @ts-expect-error
import { renderLitAsNode } from '@lion/helpers';
import { OverlayController } from '@lion/overlays';
import { LionOption } from '@lion/listbox';
@ -10,7 +9,7 @@ import {
html,
nextFrame,
unsafeStatic,
fixture,
fixture as _fixture,
} from '@open-wc/testing';
import { LionSelectInvoker, LionSelectRich } from '../index.js';
@ -19,6 +18,12 @@ import '@lion/listbox/lion-option.js';
import '@lion/listbox/lion-options.js';
import '../lion-select-rich.js';
/**
* @typedef {import('@lion/core').TemplateResult} TemplateResult
*/
const fixture = /** @type {(arg: TemplateResult) => Promise<LionSelectRich>} */ (_fixture);
/**
* @param {LionSelectRich} lionSelectEl
*/
@ -26,10 +31,16 @@ function getProtectedMembers(lionSelectEl) {
// @ts-ignore protected members allowed in test
const {
_invokerNode: invoker,
// @ts-ignore
_feedbackNode: feedback,
// @ts-ignore
_labelNode: label,
// @ts-ignore
_helpTextNode: helpText,
// @ts-ignore
_listboxNode: listbox,
// @ts-ignore
_overlayCtrl: overlay,
} = lionSelectEl;
return {
invoker,
@ -37,53 +48,53 @@ function getProtectedMembers(lionSelectEl) {
label,
helpText,
listbox,
overlay,
};
}
describe('lion-select-rich', () => {
it('clicking the label should focus the invoker', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(
html` <lion-select-rich label="foo"> </lion-select-rich> `,
));
const el = await fixture(html` <lion-select-rich label="foo"> </lion-select-rich> `);
expect(document.activeElement === document.body).to.be.true;
el._labelNode.click();
const { label } = getProtectedMembers(el);
label.click();
// @ts-ignore allow protected access in tests
expect(document.activeElement === el._invokerNode).to.be.true;
});
it('checks the first enabled option', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich>
<lion-option .choiceValue=${'Red'}></lion-option>
<lion-option .choiceValue=${'Hotpink'}></lion-option>
<lion-option .choiceValue=${'Blue'}></lion-option>
</lion-select-rich>
`));
`);
expect(el.activeIndex).to.equal(0);
expect(el.checkedIndex).to.equal(0);
});
it('still has a checked value while disabled', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich disabled>
<lion-option .choiceValue=${'Red'}>Red</lion-option>
<lion-option .choiceValue=${'Hotpink'}>Hotpink</lion-option>
<lion-option .choiceValue=${'Blue'}>Blue</lion-option>
</lion-select-rich>
`));
`);
expect(el.modelValue).to.equal('Red');
});
it('supports having no default selection initially', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich id="color" name="color" label="Favorite color" has-no-default-selected>
<lion-option .choiceValue=${'red'}>Red</lion-option>
<lion-option .choiceValue=${'hotpink'}>Hotpink</lion-option>
<lion-option .choiceValue=${'teal'}>Teal</lion-option>
</lion-select-rich>
`));
`);
const { invoker } = getProtectedMembers(el);
expect(invoker.selectedElement).to.be.undefined;
expect(el.modelValue).to.equal('');
@ -91,9 +102,7 @@ describe('lion-select-rich', () => {
describe('Invoker', () => {
it('generates an lion-select-invoker if no invoker is provided', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(
html` <lion-select-rich> </lion-select-rich> `,
));
const el = await fixture(html` <lion-select-rich> </lion-select-rich> `);
// @ts-ignore allow protected access in tests
expect(el._invokerNode).to.exist;
@ -102,24 +111,24 @@ describe('lion-select-rich', () => {
});
it('sets the first option as the selectedElement if no option is checked', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich name="foo">
<lion-option .choiceValue=${10}>Item 1</lion-option>
<lion-option .choiceValue=${20}>Item 2</lion-option>
</lion-select-rich>
`));
`);
const options = el.formElements;
// @ts-ignore allow protected access in tests
expect(el._invokerNode.selectedElement).dom.to.equal(options[0]);
});
it('syncs the selected element to the invoker', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich name="foo">
<lion-option .choiceValue=${10}>Item 1</lion-option>
<lion-option .choiceValue=${20} checked>Item 2</lion-option>
</lion-select-rich>
`));
`);
const options = el.querySelectorAll('lion-option');
// @ts-ignore allow protected access in tests
expect(el._invokerNode.selectedElement).dom.to.equal(options[1]);
@ -131,12 +140,12 @@ describe('lion-select-rich', () => {
});
it('delegates readonly to the invoker', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich readonly>
<lion-option .choiceValue=${10}>Item 1</lion-option>
<lion-option .choiceValue=${20}>Item 2</lion-option>
</lion-select-rich>
`));
`);
expect(el.hasAttribute('readonly')).to.be.true;
// @ts-ignore allow protected access in tests
@ -144,11 +153,11 @@ describe('lion-select-rich', () => {
});
it('delegates singleOption to the invoker', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich>
<lion-option .choiceValue=${10}>Item 1</lion-option>
</lion-select-rich>
`));
`);
expect(el.singleOption).to.be.true;
// @ts-ignore allow protected access in tests
@ -169,16 +178,16 @@ describe('lion-select-rich', () => {
);
const tagString = unsafeStatic(tag);
const firstOption = renderLitAsNode(
const firstOption = /** @type {LionOption} */ (renderLitAsNode(
html`<${tagString} checked .choiceValue=${10}></${tagString}>`,
);
));
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich>
${firstOption}
<${tagString} .choiceValue=${20}></${tagString}>
</lion-select-rich>
`));
`);
// @ts-ignore allow protected access in tests
expect(el._invokerNode.shadowRoot.firstElementChild.textContent).to.equal('10');
@ -191,16 +200,17 @@ describe('lion-select-rich', () => {
});
it('inherits the content width including arrow width', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich>
<lion-option .choiceValue=${10}>Item 1</lion-option>
<lion-option .choiceValue=${10}>Item 2 with long label</lion-option>
</lion-select-rich>
`));
`);
el.opened = true;
const options = el.formElements;
await el.updateComplete;
expect(el._invokerNode.clientWidth).to.equal(options[1].clientWidth);
const { invoker } = getProtectedMembers(el);
expect(invoker.clientWidth).to.equal(options[1].clientWidth);
const newOption = /** @type {LionOption} */ (document.createElement('lion-option'));
newOption.choiceValue = 30;
@ -208,26 +218,22 @@ describe('lion-select-rich', () => {
el._inputNode.appendChild(newOption);
await el.updateComplete;
expect(el._invokerNode.clientWidth).to.equal(options[2].clientWidth);
expect(invoker.clientWidth).to.equal(options[2].clientWidth);
el._inputNode.removeChild(newOption);
await el.updateComplete;
expect(el._invokerNode.clientWidth).to.equal(options[1].clientWidth);
expect(invoker.clientWidth).to.equal(options[1].clientWidth);
});
});
describe('overlay', () => {
it('should be closed by default', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(
html` <lion-select-rich></lion-select-rich> `,
));
const el = await fixture(html` <lion-select-rich></lion-select-rich> `);
expect(el.opened).to.be.false;
});
it('shows/hides the listbox via opened attribute', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(
html` <lion-select-rich></lion-select-rich> `,
));
const el = await fixture(html` <lion-select-rich></lion-select-rich> `);
el.opened = true;
await el.updateComplete;
// @ts-ignore allow protected access in tests
@ -241,10 +247,8 @@ describe('lion-select-rich', () => {
});
it('syncs opened state with overlay shown', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(
html` <lion-select-rich .opened=${true}></lion-select-rich> `,
));
const outerEl = /** @type {HTMLButtonElement} */ (await fixture(
const el = await fixture(html` <lion-select-rich .opened=${true}></lion-select-rich> `);
const outerEl = /** @type {HTMLButtonElement} */ (await _fixture(
'<button>somewhere</button>',
));
@ -257,9 +261,7 @@ describe('lion-select-rich', () => {
});
it('will focus the listbox on open and invoker on close', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(
html` <lion-select-rich></lion-select-rich> `,
));
const el = await fixture(html` <lion-select-rich></lion-select-rich> `);
// @ts-ignore allow protected access in tests
await el._overlayCtrl.show();
await el.updateComplete;
@ -278,12 +280,12 @@ describe('lion-select-rich', () => {
});
it('opens the listbox with checked option as active', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich>
<lion-option .choiceValue=${10}>Item 1</lion-option>
<lion-option .choiceValue=${20} checked>Item 2</lion-option>
</lion-select-rich>
`));
`);
// @ts-ignore allow protected access in tests
await el._overlayCtrl.show();
await el.updateComplete;
@ -294,25 +296,25 @@ describe('lion-select-rich', () => {
});
it('stays closed on click if it is disabled or readonly or has a single option', async () => {
const elReadOnly = /** @type {LionSelectRich} */ (await fixture(html`
const elReadOnly = await fixture(html`
<lion-select-rich readonly>
<lion-option .choiceValue=${10}>Item 1</lion-option>
<lion-option .choiceValue=${20} checked>Item 2</lion-option>
</lion-select-rich>
`));
`);
const elDisabled = /** @type {LionSelectRich} */ (await fixture(html`
const elDisabled = await fixture(html`
<lion-select-rich disabled>
<lion-option .choiceValue=${10}>Item 1</lion-option>
<lion-option .choiceValue=${20} checked>Item 2</lion-option>
</lion-select-rich>
`));
`);
const elSingleoption = /** @type {LionSelectRich} */ (await fixture(html`
const elSingleoption = await fixture(html`
<lion-select-rich>
<lion-option .choiceValue=${10}>Item 1</lion-option>
</lion-select-rich>
`));
`);
// @ts-ignore allow protected access in tests
elReadOnly._invokerNode.click();
@ -331,13 +333,13 @@ describe('lion-select-rich', () => {
});
it('sets inheritsReferenceWidth to min by default', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich name="favoriteColor" label="Favorite color">
<lion-option .choiceValue=${'red'}>Red</lion-option>
<lion-option .choiceValue=${'hotpink'}>Hotpink</lion-option>
<lion-option .choiceValue=${'teal'}>Teal</lion-option>
</lion-select-rich>
`));
`);
// @ts-ignore allow protected access in tests
expect(el._overlayCtrl.inheritsReferenceWidth).to.equal('min');
@ -349,26 +351,28 @@ describe('lion-select-rich', () => {
});
it('should override the inheritsWidth prop when no default selected feature is used', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich name="favoriteColor" label="Favorite color" has-no-default-selected>
<lion-option .choiceValue=${'red'}>Red</lion-option>
<lion-option .choiceValue=${'hotpink'}>Hotpink</lion-option>
<lion-option .choiceValue=${'teal'}>Teal</lion-option>
</lion-select-rich>
`));
`);
const { overlay } = getProtectedMembers(el);
// The default is min, so we override that behavior here
// @ts-ignore allow protected access in tests
el._overlayCtrl.updateConfig({ inheritsReferenceWidth: 'full' });
overlay.updateConfig({ inheritsReferenceWidth: 'full' });
el._initialInheritsReferenceWidth = 'full';
// @ts-ignore allow protected access in tests
expect(el._overlayCtrl.inheritsReferenceWidth).to.equal('full');
expect(overlay.inheritsReferenceWidth).to.equal('full');
el.opened = true;
await el.updateComplete;
// Opens while hasNoDefaultSelected = true, so we expect an override
// @ts-ignore allow protected access in tests
expect(el._overlayCtrl.inheritsReferenceWidth).to.equal('min');
expect(overlay.inheritsReferenceWidth).to.equal('min');
// Emulate selecting hotpink, it closing, and opening it again
el.modelValue = 'hotpink';
@ -378,7 +382,7 @@ describe('lion-select-rich', () => {
el.opened = true;
await el.updateComplete;
await el.updateComplete; // safari takes a little longer
await el._overlayCtrl._showComplete;
await overlay._showComplete;
// noDefaultSelected will now flip the override back to what was the initial reference width
// @ts-ignore allow protected access in tests
@ -386,12 +390,12 @@ describe('lion-select-rich', () => {
});
it('should have singleOption only if there is exactly one option', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich>
<lion-option .choiceValue=${10}>Item 1</lion-option>
<lion-option .choiceValue=${20}>Item 2</lion-option>
</lion-select-rich>
`));
`);
expect(el.singleOption).to.be.false;
// @ts-ignore allow protected access in tests
expect(el._invokerNode.singleOption).to.be.false;
@ -418,18 +422,16 @@ describe('lion-select-rich', () => {
describe('interaction-mode', () => {
it('allows to specify an interaction-mode which determines other behaviors', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich interaction-mode="mac"> </lion-select-rich>
`));
`);
expect(el.interactionMode).to.equal('mac');
});
});
describe('Keyboard navigation', () => {
it('opens the listbox with [Enter] key via click handler', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(
html` <lion-select-rich> </lion-select-rich> `,
));
const el = await fixture(html` <lion-select-rich> </lion-select-rich> `);
// @ts-ignore allow protected access in tests
el._invokerNode.click();
await aTimeout(0);
@ -437,9 +439,7 @@ describe('lion-select-rich', () => {
});
it('opens the listbox with [ ](Space) key via click handler', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(
html` <lion-select-rich> </lion-select-rich> `,
));
const el = await fixture(html` <lion-select-rich> </lion-select-rich> `);
// @ts-ignore allow protected access in tests
el._invokerNode.click();
await aTimeout(0);
@ -447,18 +447,14 @@ describe('lion-select-rich', () => {
});
it('closes the listbox with [Escape] key once opened', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(
html` <lion-select-rich opened> </lion-select-rich> `,
));
const el = await fixture(html` <lion-select-rich opened> </lion-select-rich> `);
// @ts-ignore allow protected access in tests
el._listboxNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' }));
expect(el.opened).to.be.false;
});
it('closes the listbox with [Tab] key once opened', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(
html` <lion-select-rich opened> </lion-select-rich> `,
));
const el = await fixture(html` <lion-select-rich opened> </lion-select-rich> `);
// tab can only be caught via keydown
// @ts-ignore allow protected access in tests
el._listboxNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'Tab' }));
@ -468,9 +464,7 @@ describe('lion-select-rich', () => {
describe('Mouse navigation', () => {
it('opens the listbox via click on invoker', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(
html` <lion-select-rich> </lion-select-rich> `,
));
const el = await fixture(html` <lion-select-rich> </lion-select-rich> `);
expect(el.opened).to.be.false;
// @ts-ignore allow protected access in tests
el._invokerNode.click();
@ -479,11 +473,11 @@ describe('lion-select-rich', () => {
});
it('closes the listbox when an option gets clicked', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich opened>
<lion-option .choiceValue=${10}>Item 1</lion-option>
</lion-select-rich>
`));
`);
expect(el.opened).to.be.true;
el.formElements[0].click();
expect(el.opened).to.be.false;
@ -492,9 +486,7 @@ describe('lion-select-rich', () => {
describe('Keyboard navigation Windows', () => {
it('closes the listbox with [Enter] key once opened', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(
html` <lion-select-rich opened> </lion-select-rich> `,
));
const el = await fixture(html` <lion-select-rich opened> </lion-select-rich> `);
// @ts-ignore allow protected access in tests
el._listboxNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
expect(el.opened).to.be.false;
@ -503,12 +495,12 @@ describe('lion-select-rich', () => {
describe('Keyboard navigation Mac', () => {
it('checks active item and closes the listbox with [Enter] key via click handler once opened', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich opened interaction-mode="mac">
<lion-option .choiceValue=${10}>Item 1</lion-option>
<lion-option .choiceValue=${20}>Item 2</lion-option>
</lion-select-rich>
`));
`);
// changes active but not checked
el.activeIndex = 1;
@ -520,18 +512,18 @@ describe('lion-select-rich', () => {
});
it('opens the listbox with [ArrowUp] key', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich interaction-mode="mac"> </lion-select-rich>
`));
`);
el.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowUp' }));
await el.updateComplete;
expect(el.opened).to.be.true;
});
it('opens the listbox with [ArrowDown] key', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich interaction-mode="mac"> </lion-select-rich>
`));
`);
el.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowDown' }));
await el.updateComplete;
expect(el.opened).to.be.true;
@ -540,12 +532,12 @@ describe('lion-select-rich', () => {
describe('Accessibility', () => {
it('has the right references to its inner elements', async () => {
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<lion-select-rich label="age">
<lion-option .choiceValue=${10}>Item 1</lion-option>
<lion-option .choiceValue=${20}>Item 2</lion-option>
</lion-select-rich>
`));
`);
const { invoker, feedback, label, helpText } = getProtectedMembers(el);
expect(invoker.getAttribute('aria-labelledby')).to.contain(label.id);
@ -557,9 +549,7 @@ describe('lion-select-rich', () => {
it('notifies when the listbox is expanded or not', async () => {
// smoke test for overlay functionality
const el = /** @type {LionSelectRich} */ (await fixture(
html` <lion-select-rich> </lion-select-rich> `,
));
const el = await fixture(html` <lion-select-rich> </lion-select-rich> `);
const { invoker } = getProtectedMembers(el);
expect(invoker.getAttribute('aria-expanded')).to.equal('false');
@ -619,9 +609,9 @@ describe('lion-select-rich', () => {
},
);
const mySelectContainerTag = unsafeStatic(mySelectContainerTagString);
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<${mySelectContainerTag}></${mySelectContainerTag}>
`));
`);
const selectRich = /** @type {LionSelectRich} */ (
/** @type {ShadowRoot} */ (el.shadowRoot).querySelector('lion-select-rich')
@ -667,7 +657,7 @@ describe('lion-select-rich', () => {
const mySelectTag = unsafeStatic(mySelectTagString);
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<${mySelectTag} label="Favorite color" name="color">
${Array(2).map(
@ -677,7 +667,7 @@ describe('lion-select-rich', () => {
)}
</${mySelectTag}>
`));
`);
await el.updateComplete;
// @ts-ignore allow protected member access in tests
expect(el._overlayCtrl.placementMode).to.equal('global');
@ -708,7 +698,7 @@ describe('lion-select-rich', () => {
);
const selectTag = unsafeStatic(selectTagName);
const el = /** @type {LionSelectRich} */ (await fixture(html`
const el = await fixture(html`
<${selectTag} id="color" name="color" label="Favorite color" has-no-default-selected>
<lion-option .choiceValue=${'red'}>Red</lion-option>
@ -716,7 +706,7 @@ describe('lion-select-rich', () => {
<lion-option .choiceValue=${'teal'}>Teal</lion-option>
</${selectTag}>
`));
`);
const { invoker } = getProtectedMembers(el);
expect(

View file

@ -22,10 +22,6 @@
"**/dist/**/*",
"packages/**/test-helpers",
"packages/**/docs/**/*",
"packages/combobox/test/**/*.js", // TODO: Needs to get typed!
"packages/form-integrations/test/**/*.js", // TODO: Needs to get typed!
"packages/overlays/test/utils-tests/**/*.js", // TODO: Needs to get typed!
"packages/select-rich/test/**/*.js", // TODO: Needs to get typed!
"packages/singleton-manager/demo/",
"packages/singleton-manager/test/",
// ignore test/demos for singleton manager until overlays are typed as it's used in there

View file

@ -1834,10 +1834,10 @@
"@open-wc/rollup-plugin-html" "^1.2.5"
polyfills-loader "^1.7.5"
"@open-wc/scoped-elements@^1.2.4", "@open-wc/scoped-elements@^1.3.2":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@open-wc/scoped-elements/-/scoped-elements-1.3.2.tgz#6ae54c49731bbe8c3e0b5383c989f983dcdfacf5"
integrity sha512-DoP3XA8r03tGx+IrlJwP/voLuDFkyS56kvwhmXIhpESo7M5jMt5e0zScNrawj7EMe4b5gDaJjorx2Jza8FLaLw==
"@open-wc/scoped-elements@^1.2.4", "@open-wc/scoped-elements@^1.3.3":
version "1.3.3"
resolved "https://registry.yarnpkg.com/@open-wc/scoped-elements/-/scoped-elements-1.3.3.tgz#fe008aef4d74fb00c553c900602960638fc1c7b0"
integrity sha512-vFIQVYYjFw67odUE4JzZOpctnF7S/2DX+S+clrL3bQPql7HvEnV0wMFwOWUavQTuCJi0rfU8GTcNMiUybio+Yg==
dependencies:
"@open-wc/dedupe-mixin" "^1.3.0"
lit-html "^1.0.0"