kopia lustrzana https://github.com/shoelace-style/shoelace
Merge branch 'bennypowers-fix/checkbox-emit-on-user-action-only' into next
commit
0d3d9c8233
|
|
@ -6,21 +6,21 @@ import type SlAlert from './alert';
|
|||
|
||||
describe('<sl-alert>', () => {
|
||||
it('should be visible with the open attribute', async () => {
|
||||
const el = await fixture(html` <sl-alert open>I am an alert</sl-alert> `);
|
||||
const el = await fixture<SlAlert>(html` <sl-alert open>I am an alert</sl-alert> `);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
|
||||
expect(base.hidden).to.be.false;
|
||||
});
|
||||
|
||||
it('should not be visible without the open attribute', async () => {
|
||||
const el = await fixture(html` <sl-alert>I am an alert</sl-alert> `);
|
||||
const el = await fixture<SlAlert>(html` <sl-alert>I am an alert</sl-alert> `);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
|
||||
expect(base.hidden).to.be.true;
|
||||
});
|
||||
|
||||
it('should emit sl-show and sl-after-show when calling show()', async () => {
|
||||
const el = (await fixture(html` <sl-alert>I am an alert</sl-alert> `)) as SlAlert;
|
||||
const el = await fixture<SlAlert>(html` <sl-alert>I am an alert</sl-alert> `);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
const showHandler = sinon.spy();
|
||||
const afterShowHandler = sinon.spy();
|
||||
|
|
@ -38,7 +38,7 @@ describe('<sl-alert>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-hide and sl-after-hide when calling hide()', async () => {
|
||||
const el = (await fixture(html` <sl-alert open>I am an alert</sl-alert> `)) as SlAlert;
|
||||
const el = await fixture<SlAlert>(html` <sl-alert open>I am an alert</sl-alert> `);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
const hideHandler = sinon.spy();
|
||||
const afterHideHandler = sinon.spy();
|
||||
|
|
@ -56,7 +56,7 @@ describe('<sl-alert>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-show and sl-after-show when setting open = true', async () => {
|
||||
const el = (await fixture(html` <sl-alert>I am an alert</sl-alert> `)) as SlAlert;
|
||||
const el = await fixture<SlAlert>(html` <sl-alert>I am an alert</sl-alert> `);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
const showHandler = sinon.spy();
|
||||
const afterShowHandler = sinon.spy();
|
||||
|
|
@ -74,7 +74,7 @@ describe('<sl-alert>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-hide and sl-after-hide when setting open = false', async () => {
|
||||
const el = (await fixture(html` <sl-alert open>I am an alert</sl-alert> `)) as SlAlert;
|
||||
const el = await fixture<SlAlert>(html` <sl-alert open>I am an alert</sl-alert> `);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
const hideHandler = sinon.spy();
|
||||
const afterHideHandler = sinon.spy();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
import { expect, fixture, html, oneEvent } from '@open-wc/testing';
|
||||
import { sendKeys } from '@web/test-runner-commands';
|
||||
|
||||
import '../../../dist/shoelace.js';
|
||||
import type SlCheckbox from './checkbox';
|
||||
|
||||
describe('<sl-checkbox>', () => {
|
||||
it('should be disabled with the disabled attribute', async () => {
|
||||
const el = await fixture<SlCheckbox>(html` <sl-checkbox disabled></sl-checkbox> `);
|
||||
const checkbox = el.shadowRoot?.querySelector('input');
|
||||
|
||||
expect(checkbox.disabled).to.be.true;
|
||||
});
|
||||
|
||||
it('should be valid by default', async () => {
|
||||
const el = await fixture<SlCheckbox>(html` <sl-checkbox></sl-checkbox> `);
|
||||
|
||||
expect(el.invalid).to.be.false;
|
||||
});
|
||||
|
||||
it('should fire sl-change when clicked', async () => {
|
||||
const el = await fixture<SlCheckbox>(html` <sl-checkbox></sl-checkbox> `);
|
||||
setTimeout(() => el.shadowRoot?.querySelector('input').click());
|
||||
const event = await oneEvent(el, 'sl-change');
|
||||
expect(event.target).to.equal(el);
|
||||
expect(el.checked).to.be.true;
|
||||
});
|
||||
|
||||
it('should fire sl-change when toggled via keyboard', async () => {
|
||||
const el = await fixture<SlCheckbox>(html` <sl-checkbox></sl-checkbox> `);
|
||||
const input = el.shadowRoot?.querySelector('input');
|
||||
input.focus();
|
||||
setTimeout(() => sendKeys({ press: ' ' }));
|
||||
const event = await oneEvent(el, 'sl-change');
|
||||
expect(event.target).to.equal(el);
|
||||
expect(el.checked).to.be.true;
|
||||
});
|
||||
|
||||
it('should not fire sl-change when checked is set by javascript', async () => {
|
||||
const el = await fixture<SlCheckbox>(html` <sl-checkbox></sl-checkbox> `);
|
||||
el.addEventListener('sl-change', () => expect.fail('event fired'));
|
||||
el.checked = true;
|
||||
await el.updateComplete;
|
||||
el.checked = false;
|
||||
await el.updateComplete;
|
||||
});
|
||||
});
|
||||
|
|
@ -90,6 +90,7 @@ export default class SlCheckbox extends LitElement {
|
|||
handleClick() {
|
||||
this.checked = !this.checked;
|
||||
this.indeterminate = false;
|
||||
emit(this, 'sl-change');
|
||||
}
|
||||
|
||||
handleBlur() {
|
||||
|
|
@ -121,7 +122,6 @@ export default class SlCheckbox extends LitElement {
|
|||
@watch('indeterminate', { waitUntilFirstUpdate: true })
|
||||
handleStateChange() {
|
||||
this.invalid = !this.input.checkValidity();
|
||||
emit(this, 'sl-change');
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import type SlColorPicker from './color-picker';
|
|||
|
||||
describe('<sl-color-picker>', () => {
|
||||
it('should emit change and show correct color when the value changes', async () => {
|
||||
const el = (await fixture(html` <sl-color-picker></sl-color-picker> `)) as SlColorPicker;
|
||||
const el = await fixture<SlColorPicker>(html` <sl-color-picker></sl-color-picker> `);
|
||||
const trigger = el.shadowRoot.querySelector('[part="trigger"]') as HTMLElement;
|
||||
const changeHandler = sinon.spy();
|
||||
const color = 'rgb(255, 204, 0)';
|
||||
|
|
@ -21,21 +21,21 @@ describe('<sl-color-picker>', () => {
|
|||
});
|
||||
|
||||
it('should render in a dropdown', async () => {
|
||||
const el = (await fixture(html` <sl-color-picker></sl-color-picker> `)) as SlColorPicker;
|
||||
const el = await fixture<SlColorPicker>(html` <sl-color-picker></sl-color-picker> `);
|
||||
const dropdown = el.shadowRoot.querySelector('sl-dropdown');
|
||||
|
||||
expect(dropdown).to.exist;
|
||||
});
|
||||
|
||||
it('should not render in a dropdown when inline is enabled', async () => {
|
||||
const el = (await fixture(html` <sl-color-picker inline></sl-color-picker> `)) as SlColorPicker;
|
||||
const el = await fixture<SlColorPicker>(html` <sl-color-picker inline></sl-color-picker> `);
|
||||
const dropdown = el.shadowRoot.querySelector('sl-dropdown');
|
||||
|
||||
expect(dropdown).to.not.exist;
|
||||
});
|
||||
|
||||
it('should show opacity slider when opacity is enabled', async () => {
|
||||
const el = (await fixture(html` <sl-color-picker opacity></sl-color-picker> `)) as SlColorPicker;
|
||||
const el = await fixture<SlColorPicker>(html` <sl-color-picker opacity></sl-color-picker> `);
|
||||
const opacitySlider = el.shadowRoot.querySelector('[part*="opacity-slider"]') as HTMLElement;
|
||||
|
||||
expect(opacitySlider).to.exist;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import type SlDetails from './details';
|
|||
|
||||
describe('<sl-details>', () => {
|
||||
it('should be visible with the open attribute', async () => {
|
||||
const el = await fixture(html`
|
||||
const el = await fixture<SlDetails>(html`
|
||||
<sl-details open>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
|
||||
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
|
|
@ -19,7 +19,7 @@ describe('<sl-details>', () => {
|
|||
});
|
||||
|
||||
it('should not be visible without the open attribute', async () => {
|
||||
const el = await fixture(html`
|
||||
const el = await fixture<SlDetails>(html`
|
||||
<sl-details>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
|
||||
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
|
|
@ -32,13 +32,13 @@ describe('<sl-details>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-show and sl-after-show when calling show()', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDetails>(html`
|
||||
<sl-details>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
|
||||
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat.
|
||||
</sl-details>
|
||||
`)) as SlDetails;
|
||||
`);
|
||||
const body = el.shadowRoot?.querySelector('.details__body') as HTMLElement;
|
||||
const showHandler = sinon.spy();
|
||||
const afterShowHandler = sinon.spy();
|
||||
|
|
@ -56,13 +56,13 @@ describe('<sl-details>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-hide and sl-after-hide when calling hide()', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDetails>(html`
|
||||
<sl-details open>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
|
||||
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat.
|
||||
</sl-details>
|
||||
`)) as SlDetails;
|
||||
`);
|
||||
const body = el.shadowRoot?.querySelector('.details__body') as HTMLElement;
|
||||
const hideHandler = sinon.spy();
|
||||
const afterHideHandler = sinon.spy();
|
||||
|
|
@ -80,13 +80,13 @@ describe('<sl-details>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-show and sl-after-show when setting open = true', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDetails>(html`
|
||||
<sl-details>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
|
||||
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat.
|
||||
</sl-details>
|
||||
`)) as SlDetails;
|
||||
`);
|
||||
const body = el.shadowRoot?.querySelector('.details__body') as HTMLElement;
|
||||
const showHandler = sinon.spy();
|
||||
const afterShowHandler = sinon.spy();
|
||||
|
|
@ -104,13 +104,13 @@ describe('<sl-details>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-hide and sl-after-hide when setting open = false', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDetails>(html`
|
||||
<sl-details open>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
|
||||
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat.
|
||||
</sl-details>
|
||||
`)) as SlDetails;
|
||||
`);
|
||||
const body = el.shadowRoot?.querySelector('.details__body') as HTMLElement;
|
||||
const hideHandler = sinon.spy();
|
||||
const afterHideHandler = sinon.spy();
|
||||
|
|
@ -128,7 +128,7 @@ describe('<sl-details>', () => {
|
|||
});
|
||||
|
||||
it('should be the correct size after opening more than one instance', async () => {
|
||||
const el = await fixture(html`
|
||||
const el = await fixture<SlDetails>(html`
|
||||
<div>
|
||||
<sl-details>
|
||||
<div style="height: 200px;"></div>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import type SlDialog from './dialog';
|
|||
|
||||
describe('<sl-dialog>', () => {
|
||||
it('should be visible with the open attribute', async () => {
|
||||
const el = await fixture(html`
|
||||
const el = await fixture<SlDialog>(html`
|
||||
<sl-dialog open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sl-dialog>
|
||||
`);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
|
|
@ -15,16 +15,18 @@ describe('<sl-dialog>', () => {
|
|||
});
|
||||
|
||||
it('should not be visible without the open attribute', async () => {
|
||||
const el = await fixture(html` <sl-dialog>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sl-dialog> `);
|
||||
const el = await fixture<SlDialog>(
|
||||
html` <sl-dialog>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sl-dialog> `
|
||||
);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
|
||||
expect(base.hidden).to.be.true;
|
||||
});
|
||||
|
||||
it('should emit sl-show and sl-after-show when calling show()', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDialog>(html`
|
||||
<sl-dialog>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sl-dialog>
|
||||
`)) as SlDialog;
|
||||
`);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
const showHandler = sinon.spy();
|
||||
const afterShowHandler = sinon.spy();
|
||||
|
|
@ -42,9 +44,9 @@ describe('<sl-dialog>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-hide and sl-after-hide when calling hide()', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDialog>(html`
|
||||
<sl-dialog open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sl-dialog>
|
||||
`)) as SlDialog;
|
||||
`);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
const hideHandler = sinon.spy();
|
||||
const afterHideHandler = sinon.spy();
|
||||
|
|
@ -62,9 +64,9 @@ describe('<sl-dialog>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-show and sl-after-show when setting open = true', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDialog>(html`
|
||||
<sl-dialog>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sl-dialog>
|
||||
`)) as SlDialog;
|
||||
`);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
const showHandler = sinon.spy();
|
||||
const afterShowHandler = sinon.spy();
|
||||
|
|
@ -82,9 +84,9 @@ describe('<sl-dialog>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-hide and sl-after-hide when setting open = false', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDialog>(html`
|
||||
<sl-dialog open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sl-dialog>
|
||||
`)) as SlDialog;
|
||||
`);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
const hideHandler = sinon.spy();
|
||||
const afterHideHandler = sinon.spy();
|
||||
|
|
@ -102,9 +104,9 @@ describe('<sl-dialog>', () => {
|
|||
});
|
||||
|
||||
it('should not close when sl-request-close is prevented', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDialog>(html`
|
||||
<sl-dialog open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sl-dialog>
|
||||
`)) as SlDialog;
|
||||
`);
|
||||
const overlay = el.shadowRoot?.querySelector('[part="overlay"]') as HTMLElement;
|
||||
|
||||
el.addEventListener('sl-request-close', event => event.preventDefault());
|
||||
|
|
@ -114,7 +116,7 @@ describe('<sl-dialog>', () => {
|
|||
});
|
||||
|
||||
it('should allow initial focus to be set', async () => {
|
||||
const el = (await fixture(html` <sl-dialog><input /></sl-dialog> `)) as SlDialog;
|
||||
const el = await fixture<SlDialog>(html` <sl-dialog><input /></sl-dialog> `);
|
||||
const input = el.querySelector('input');
|
||||
const initialFocusHandler = sinon.spy(event => {
|
||||
event.preventDefault();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import type SlDrawer from './drawer';
|
|||
|
||||
describe('<sl-drawer>', () => {
|
||||
it('should be visible with the open attribute', async () => {
|
||||
const el = await fixture(html`
|
||||
const el = await fixture<SlDrawer>(html`
|
||||
<sl-drawer open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sl-drawer>
|
||||
`);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
|
|
@ -15,16 +15,18 @@ describe('<sl-drawer>', () => {
|
|||
});
|
||||
|
||||
it('should not be visible without the open attribute', async () => {
|
||||
const el = await fixture(html` <sl-drawer>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sl-drawer> `);
|
||||
const el = await fixture<SlDrawer>(
|
||||
html` <sl-drawer>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sl-drawer> `
|
||||
);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
|
||||
expect(base.hidden).to.be.true;
|
||||
});
|
||||
|
||||
it('should emit sl-show and sl-after-show when calling show()', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDrawer>(html`
|
||||
<sl-drawer>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sl-drawer>
|
||||
`)) as SlDrawer;
|
||||
`);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
const showHandler = sinon.spy();
|
||||
const afterShowHandler = sinon.spy();
|
||||
|
|
@ -42,9 +44,9 @@ describe('<sl-drawer>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-hide and sl-after-hide when calling hide()', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDrawer>(html`
|
||||
<sl-drawer open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sl-drawer>
|
||||
`)) as SlDrawer;
|
||||
`);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
const hideHandler = sinon.spy();
|
||||
const afterHideHandler = sinon.spy();
|
||||
|
|
@ -62,9 +64,9 @@ describe('<sl-drawer>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-show and sl-after-show when setting open = true', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDrawer>(html`
|
||||
<sl-drawer>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sl-drawer>
|
||||
`)) as SlDrawer;
|
||||
`);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
const showHandler = sinon.spy();
|
||||
const afterShowHandler = sinon.spy();
|
||||
|
|
@ -82,9 +84,9 @@ describe('<sl-drawer>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-hide and sl-after-hide when setting open = false', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDrawer>(html`
|
||||
<sl-drawer open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sl-drawer>
|
||||
`)) as SlDrawer;
|
||||
`);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
const hideHandler = sinon.spy();
|
||||
const afterHideHandler = sinon.spy();
|
||||
|
|
@ -102,9 +104,9 @@ describe('<sl-drawer>', () => {
|
|||
});
|
||||
|
||||
it('should not close when sl-request-close is prevented', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDrawer>(html`
|
||||
<sl-drawer open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sl-drawer>
|
||||
`)) as SlDrawer;
|
||||
`);
|
||||
const overlay = el.shadowRoot?.querySelector('[part="overlay"]') as HTMLElement;
|
||||
|
||||
el.addEventListener('sl-request-close', event => event.preventDefault());
|
||||
|
|
@ -114,7 +116,7 @@ describe('<sl-drawer>', () => {
|
|||
});
|
||||
|
||||
it('should allow initial focus to be set', async () => {
|
||||
const el = (await fixture(html` <sl-drawer><input /></sl-drawer> `)) as SlDrawer;
|
||||
const el = await fixture<SlDrawer>(html` <sl-drawer><input /></sl-drawer> `);
|
||||
const input = el.querySelector('input');
|
||||
const initialFocusHandler = sinon.spy(event => {
|
||||
event.preventDefault();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import type SlDropdown from './dropdown';
|
|||
|
||||
describe('<sl-dropdown>', () => {
|
||||
it('should be visible with the open attribute', async () => {
|
||||
const el = await fixture(html`
|
||||
const el = await fixture<SlDropdown>(html`
|
||||
<sl-dropdown open>
|
||||
<sl-button slot="trigger" caret>Toggle</sl-button>
|
||||
<sl-menu>
|
||||
|
|
@ -22,7 +22,7 @@ describe('<sl-dropdown>', () => {
|
|||
});
|
||||
|
||||
it('should not be visible without the open attribute', async () => {
|
||||
const el = await fixture(html`
|
||||
const el = await fixture<SlDropdown>(html`
|
||||
<sl-dropdown>
|
||||
<sl-button slot="trigger" caret>Toggle</sl-button>
|
||||
<sl-menu>
|
||||
|
|
@ -38,7 +38,7 @@ describe('<sl-dropdown>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-show and sl-after-show when calling show()', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDropdown>(html`
|
||||
<sl-dropdown>
|
||||
<sl-button slot="trigger" caret>Toggle</sl-button>
|
||||
<sl-menu>
|
||||
|
|
@ -47,7 +47,7 @@ describe('<sl-dropdown>', () => {
|
|||
<sl-menu-item>Item 3</sl-menu-item>
|
||||
</sl-menu>
|
||||
</sl-dropdown>
|
||||
`)) as SlDropdown;
|
||||
`);
|
||||
const panel = el.shadowRoot?.querySelector('[part="panel"]') as HTMLElement;
|
||||
const showHandler = sinon.spy();
|
||||
const afterShowHandler = sinon.spy();
|
||||
|
|
@ -65,7 +65,7 @@ describe('<sl-dropdown>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-hide and sl-after-hide when calling hide()', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDropdown>(html`
|
||||
<sl-dropdown open>
|
||||
<sl-button slot="trigger" caret>Toggle</sl-button>
|
||||
<sl-menu>
|
||||
|
|
@ -74,7 +74,7 @@ describe('<sl-dropdown>', () => {
|
|||
<sl-menu-item>Item 3</sl-menu-item>
|
||||
</sl-menu>
|
||||
</sl-dropdown>
|
||||
`)) as SlDropdown;
|
||||
`);
|
||||
const panel = el.shadowRoot?.querySelector('[part="panel"]') as HTMLElement;
|
||||
const hideHandler = sinon.spy();
|
||||
const afterHideHandler = sinon.spy();
|
||||
|
|
@ -92,7 +92,7 @@ describe('<sl-dropdown>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-show and sl-after-show when setting open = true', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDropdown>(html`
|
||||
<sl-dropdown>
|
||||
<sl-button slot="trigger" caret>Toggle</sl-button>
|
||||
<sl-menu>
|
||||
|
|
@ -101,7 +101,7 @@ describe('<sl-dropdown>', () => {
|
|||
<sl-menu-item>Item 3</sl-menu-item>
|
||||
</sl-menu>
|
||||
</sl-dropdown>
|
||||
`)) as SlDropdown;
|
||||
`);
|
||||
const panel = el.shadowRoot?.querySelector('[part="panel"]') as HTMLElement;
|
||||
const showHandler = sinon.spy();
|
||||
const afterShowHandler = sinon.spy();
|
||||
|
|
@ -119,7 +119,7 @@ describe('<sl-dropdown>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-hide and sl-after-hide when setting open = false', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlDropdown>(html`
|
||||
<sl-dropdown open>
|
||||
<sl-button slot="trigger" caret>Toggle</sl-button>
|
||||
<sl-menu>
|
||||
|
|
@ -128,7 +128,7 @@ describe('<sl-dropdown>', () => {
|
|||
<sl-menu-item>Item 3</sl-menu-item>
|
||||
</sl-menu>
|
||||
</sl-dropdown>
|
||||
`)) as SlDropdown;
|
||||
`);
|
||||
const panel = el.shadowRoot?.querySelector('[part="panel"]') as HTMLElement;
|
||||
const hideHandler = sinon.spy();
|
||||
const afterHideHandler = sinon.spy();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ import type SlInclude from './include';
|
|||
|
||||
describe('<sl-include>', () => {
|
||||
it('should load content and emit sl-load', async () => {
|
||||
const el = await fixture(html` <sl-include src="https://jsonplaceholder.typicode.com/posts/1"></sl-include> `);
|
||||
const el = await fixture<SlInclude>(
|
||||
html` <sl-include src="https://jsonplaceholder.typicode.com/posts/1"></sl-include> `
|
||||
);
|
||||
const loadHandler = sinon.spy();
|
||||
|
||||
el.addEventListener('sl-load', loadHandler);
|
||||
|
|
@ -17,7 +19,7 @@ describe('<sl-include>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-error when content cannot be loaded', async () => {
|
||||
const el = await fixture(html` <sl-include src="https://404"></sl-include> `);
|
||||
const el = await fixture<SlInclude>(html` <sl-include src="https://404"></sl-include> `);
|
||||
const loadHandler = sinon.spy();
|
||||
|
||||
el.addEventListener('sl-error', loadHandler);
|
||||
|
|
|
|||
|
|
@ -6,26 +6,26 @@ import type SlInput from './input';
|
|||
|
||||
describe('<sl-input>', () => {
|
||||
it('should be disabled with the disabled attribute', async () => {
|
||||
const el = await fixture(html` <sl-input disabled></sl-input> `);
|
||||
const el = await fixture<SlInput>(html` <sl-input disabled></sl-input> `);
|
||||
const input = el.shadowRoot?.querySelector('[part="input"]') as HTMLInputElement;
|
||||
|
||||
expect(input.disabled).to.be.true;
|
||||
});
|
||||
|
||||
it('should be valid by default', async () => {
|
||||
const el = (await fixture(html` <sl-input></sl-input> `)) as SlInput;
|
||||
const el = await fixture<SlInput>(html` <sl-input></sl-input> `);
|
||||
|
||||
expect(el.invalid).to.be.false;
|
||||
});
|
||||
|
||||
it('should be invalid when required and empty', async () => {
|
||||
const el = (await fixture(html` <sl-input required></sl-input> `)) as SlInput;
|
||||
const el = await fixture<SlInput>(html` <sl-input required></sl-input> `);
|
||||
|
||||
expect(el.invalid).to.be.true;
|
||||
});
|
||||
|
||||
it('should be invalid when required and after removing disabled ', async () => {
|
||||
const el = (await fixture(html` <sl-input disabled required></sl-input> `)) as SlInput;
|
||||
const el = await fixture<SlInput>(html` <sl-input disabled required></sl-input> `);
|
||||
|
||||
el.disabled = false;
|
||||
await el.updateComplete;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
import { expect, fixture, html, oneEvent } from '@open-wc/testing';
|
||||
import { sendKeys } from '@web/test-runner-commands';
|
||||
|
||||
import '../../../dist/shoelace.js';
|
||||
import type SlRadio from './radio';
|
||||
|
||||
describe('<sl-radio>', () => {
|
||||
it('should be disabled with the disabled attribute', async () => {
|
||||
const el = await fixture<SlRadio>(html` <sl-radio disabled></sl-radio> `);
|
||||
const radio = el.shadowRoot?.querySelector('input');
|
||||
|
||||
expect(radio.disabled).to.be.true;
|
||||
});
|
||||
|
||||
it('should be valid by default', async () => {
|
||||
const el = await fixture<SlRadio>(html` <sl-radio></sl-radio> `);
|
||||
|
||||
expect(el.invalid).to.be.false;
|
||||
});
|
||||
|
||||
it('should fire sl-change when clicked', async () => {
|
||||
const el = await fixture<SlRadio>(html` <sl-radio></sl-radio> `);
|
||||
setTimeout(() => el.shadowRoot?.querySelector('input').click());
|
||||
const event = await oneEvent(el, 'sl-change');
|
||||
expect(event.target).to.equal(el);
|
||||
expect(el.checked).to.be.true;
|
||||
});
|
||||
|
||||
it('should fire sl-change when toggled via keyboard', async () => {
|
||||
const el = await fixture<SlRadio>(html` <sl-radio></sl-radio> `);
|
||||
const input = el.shadowRoot?.querySelector('input');
|
||||
input.focus();
|
||||
setTimeout(() => sendKeys({ press: ' ' }));
|
||||
const event = await oneEvent(el, 'sl-change');
|
||||
expect(event.target).to.equal(el);
|
||||
expect(el.checked).to.be.true;
|
||||
});
|
||||
|
||||
it('should not fire sl-change when checked is set by javascript', async () => {
|
||||
const el = await fixture<SlRadio>(html` <sl-radio></sl-radio> `);
|
||||
el.addEventListener('sl-change', () => expect.fail('event fired'));
|
||||
el.checked = true;
|
||||
await el.updateComplete;
|
||||
el.checked = false;
|
||||
await el.updateComplete;
|
||||
});
|
||||
});
|
||||
|
|
@ -104,11 +104,11 @@ export default class SlRadio extends LitElement {
|
|||
if (this.checked) {
|
||||
this.getSiblingRadios().map(radio => (radio.checked = false));
|
||||
}
|
||||
emit(this, 'sl-change');
|
||||
}
|
||||
|
||||
handleClick() {
|
||||
this.checked = true;
|
||||
emit(this, 'sl-change');
|
||||
}
|
||||
|
||||
@watch('disabled')
|
||||
|
|
|
|||
|
|
@ -6,13 +6,13 @@ import type SlSelect from './select';
|
|||
|
||||
describe('<sl-select>', () => {
|
||||
it('should emit sl-change when the value changes', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlSelect>(html`
|
||||
<sl-select>
|
||||
<sl-menu-item value="option-1">Option 1</sl-menu-item>
|
||||
<sl-menu-item value="option-2">Option 2</sl-menu-item>
|
||||
<sl-menu-item value="option-3">Option 3</sl-menu-item>
|
||||
</sl-select>
|
||||
`)) as SlSelect;
|
||||
`);
|
||||
const changeHandler = sinon.spy();
|
||||
|
||||
el.addEventListener('sl-change', changeHandler);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
import { expect, fixture, html, oneEvent } from '@open-wc/testing';
|
||||
import { sendKeys } from '@web/test-runner-commands';
|
||||
|
||||
import '../../../dist/shoelace.js';
|
||||
import type SlSwitch from './switch';
|
||||
|
||||
describe('<sl-switch>', () => {
|
||||
it('should be disabled with the disabled attribute', async () => {
|
||||
const el = await fixture<SlSwitch>(html` <sl-switch disabled></sl-switch> `);
|
||||
const input = el.shadowRoot?.querySelector('input');
|
||||
|
||||
expect(input.disabled).to.be.true;
|
||||
});
|
||||
|
||||
it('should be valid by default', async () => {
|
||||
const el = await fixture<SlSwitch>(html` <sl-switch></sl-switch> `);
|
||||
|
||||
expect(el.invalid).to.be.false;
|
||||
});
|
||||
|
||||
it('should fire sl-change when clicked', async () => {
|
||||
const el = await fixture<SlSwitch>(html` <sl-switch></sl-switch> `);
|
||||
setTimeout(() => el.shadowRoot?.querySelector('input').click());
|
||||
const event = await oneEvent(el, 'sl-change');
|
||||
expect(event.target).to.equal(el);
|
||||
expect(el.checked).to.be.true;
|
||||
});
|
||||
|
||||
it('should fire sl-change when toggled with spacebar', async () => {
|
||||
const el = await fixture<SlSwitch>(html` <sl-switch></sl-switch> `);
|
||||
el.focus();
|
||||
setTimeout(() => sendKeys({ press: ' ' }));
|
||||
const event = await oneEvent(el, 'sl-change');
|
||||
expect(event.target).to.equal(el);
|
||||
expect(el.checked).to.be.true;
|
||||
});
|
||||
|
||||
// TODO - arrow key doesn't seem to be sending
|
||||
// TODO - test for left arrow too
|
||||
// it('should fire sl-change when toggled with the right arrow', async () => {
|
||||
// const el = await fixture<SlSwitch>(html` <sl-switch></sl-switch> `);
|
||||
// el.focus();
|
||||
// setTimeout(() => sendKeys({ press: 'ArrowRight' }));
|
||||
// const event = await oneEvent(el, 'sl-change');
|
||||
// expect(event.target).to.equal(el);
|
||||
// expect(el.checked).to.be.true;
|
||||
// });
|
||||
|
||||
it('should not fire sl-change when checked is set by javascript', async () => {
|
||||
const el = await fixture<SlSwitch>(html` <sl-switch></sl-switch> `);
|
||||
el.addEventListener('sl-change', () => expect.fail('event fired'));
|
||||
el.checked = true;
|
||||
await el.updateComplete;
|
||||
el.checked = false;
|
||||
await el.updateComplete;
|
||||
});
|
||||
});
|
||||
|
|
@ -97,12 +97,12 @@ export default class SlSwitch extends LitElement {
|
|||
if (this.input) {
|
||||
this.input.checked = this.checked;
|
||||
this.invalid = !this.input.checkValidity();
|
||||
emit(this, 'sl-change');
|
||||
}
|
||||
}
|
||||
|
||||
handleClick() {
|
||||
this.checked = !this.checked;
|
||||
emit(this, 'sl-change');
|
||||
}
|
||||
|
||||
@watch('disabled')
|
||||
|
|
@ -123,11 +123,13 @@ export default class SlSwitch extends LitElement {
|
|||
if (event.key === 'ArrowLeft') {
|
||||
event.preventDefault();
|
||||
this.checked = false;
|
||||
// emit(this, 'sl-change');
|
||||
}
|
||||
|
||||
if (event.key === 'ArrowRight') {
|
||||
event.preventDefault();
|
||||
this.checked = true;
|
||||
// emit(this, 'sl-change');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,26 +6,26 @@ import type SlTextarea from './textarea';
|
|||
|
||||
describe('<sl-textarea>', () => {
|
||||
it('should be disabled with the disabled attribute', async () => {
|
||||
const el = await fixture(html` <sl-textarea disabled></sl-textarea> `);
|
||||
const el = await fixture<SlTextarea>(html` <sl-textarea disabled></sl-textarea> `);
|
||||
const textarea = el.shadowRoot?.querySelector('[part="textarea"]') as HTMLInputElement;
|
||||
|
||||
expect(textarea.disabled).to.be.true;
|
||||
});
|
||||
|
||||
it('should be valid by default', async () => {
|
||||
const el = (await fixture(html` <sl-textarea></sl-textarea> `)) as SlTextarea;
|
||||
const el = await fixture<SlTextarea>(html` <sl-textarea></sl-textarea> `);
|
||||
|
||||
expect(el.invalid).to.be.false;
|
||||
});
|
||||
|
||||
it('should be invalid when required and empty', async () => {
|
||||
const el = (await fixture(html` <sl-textarea required></sl-textarea> `)) as SlTextarea;
|
||||
const el = await fixture<SlTextarea>(html` <sl-textarea required></sl-textarea> `);
|
||||
|
||||
expect(el.invalid).to.be.true;
|
||||
});
|
||||
|
||||
it('should be invalid when required and after removing disabled ', async () => {
|
||||
const el = (await fixture(html` <sl-textarea disabled required></sl-textarea> `)) as SlTextarea;
|
||||
const el = await fixture<SlTextarea>(html` <sl-textarea disabled required></sl-textarea> `);
|
||||
|
||||
el.disabled = false;
|
||||
await el.updateComplete;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import type SlTooltip from './tooltip';
|
|||
|
||||
describe('<sl-tooltip>', () => {
|
||||
it('should be visible with the open attribute', async () => {
|
||||
const el = await fixture(html`
|
||||
const el = await fixture<SlTooltip>(html`
|
||||
<sl-tooltip content="This is a tooltip" open>
|
||||
<sl-button>Hover Me</sl-button>
|
||||
</sl-tooltip>
|
||||
|
|
@ -17,7 +17,7 @@ describe('<sl-tooltip>', () => {
|
|||
});
|
||||
|
||||
it('should not be visible without the open attribute', async () => {
|
||||
const el = await fixture(html`
|
||||
const el = await fixture<SlTooltip>(html`
|
||||
<sl-tooltip content="This is a tooltip">
|
||||
<sl-button>Hover Me</sl-button>
|
||||
</sl-tooltip>
|
||||
|
|
@ -28,11 +28,11 @@ describe('<sl-tooltip>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-show and sl-after-show when calling show()', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlTooltip>(html`
|
||||
<sl-tooltip content="This is a tooltip">
|
||||
<sl-button>Hover Me</sl-button>
|
||||
</sl-tooltip>
|
||||
`)) as SlTooltip;
|
||||
`);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
const showHandler = sinon.spy();
|
||||
const afterShowHandler = sinon.spy();
|
||||
|
|
@ -50,11 +50,11 @@ describe('<sl-tooltip>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-hide and sl-after-hide when calling hide()', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlTooltip>(html`
|
||||
<sl-tooltip content="This is a tooltip" open>
|
||||
<sl-button>Hover Me</sl-button>
|
||||
</sl-tooltip>
|
||||
`)) as SlTooltip;
|
||||
`);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
const hideHandler = sinon.spy();
|
||||
const afterHideHandler = sinon.spy();
|
||||
|
|
@ -72,11 +72,11 @@ describe('<sl-tooltip>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-show and sl-after-show when setting open = true', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlTooltip>(html`
|
||||
<sl-tooltip content="This is a tooltip">
|
||||
<sl-button>Hover Me</sl-button>
|
||||
</sl-tooltip>
|
||||
`)) as SlTooltip;
|
||||
`);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
const showHandler = sinon.spy();
|
||||
const afterShowHandler = sinon.spy();
|
||||
|
|
@ -94,11 +94,11 @@ describe('<sl-tooltip>', () => {
|
|||
});
|
||||
|
||||
it('should emit sl-hide and sl-after-hide when setting open = false', async () => {
|
||||
const el = (await fixture(html`
|
||||
const el = await fixture<SlTooltip>(html`
|
||||
<sl-tooltip content="This is a tooltip" open>
|
||||
<sl-button>Hover Me</sl-button>
|
||||
</sl-tooltip>
|
||||
`)) as SlTooltip;
|
||||
`);
|
||||
const base = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||
const hideHandler = sinon.spy();
|
||||
const afterHideHandler = sinon.spy();
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue